From 9f24cdb355bff38f788c6b2cb6e1f8bfce0b7e5b Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 16:53:44 +0200 Subject: [PATCH 01/61] Added Author Link in BeatmapInfoWedge --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 29 +++++++++------------ 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 4069dc82ed..14e5831ef9 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -29,6 +29,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Ranking.Expanded; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select { @@ -307,7 +308,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = getMapper(metadata) + Children = new[] { getMapper(metadata) }, }, infoLabelContainer = new FillFlowContainer { @@ -430,24 +431,20 @@ namespace osu.Game.Screens.Select ForceRedraw(); } - private OsuSpriteText[] getMapper(BeatmapMetadata metadata) + private LinkFlowContainer getMapper(BeatmapMetadata metadata) { - if (string.IsNullOrEmpty(metadata.Author?.Username)) - return Array.Empty(); + if (metadata.Author == null) + return new LinkFlowContainer(); - return new[] + return new LinkFlowContainer(s => { - new OsuSpriteText - { - Text = "mapped by ", - Font = OsuFont.GetFont(size: 15), - }, - new OsuSpriteText - { - Text = metadata.Author.Username, - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15), - } - }; + s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15); + }).With(d => + { + d.AutoSizeAxes = Axes.Both; + d.AddText("mapped by "); + d.AddUserLink(metadata.Author); + }); } protected override void Dispose(bool isDisposing) From eb977312ed71bee57676714afb2a81c0522bdd9d Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 16:54:29 +0200 Subject: [PATCH 02/61] Added Author link in BeatmapSet Overlay --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 31c1439c8f..1ffcf9722a 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -13,6 +13,8 @@ using osuTK.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; +using osu.Game.Users; +using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.BeatmapSet { @@ -50,7 +52,7 @@ namespace osu.Game.Overlays.BeatmapSet fields.Children = new Drawable[] { - new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), + new Field("mapped by", BeatmapSet.Metadata.Author, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold)) { Margin = new MarginPadding { Top = 5 }, @@ -146,6 +148,25 @@ namespace osu.Game.Overlays.BeatmapSet } }; } + + public Field(string first, User second, FontUsage secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new LinkFlowContainer(s => + { + s.Font = OsuFont.GetFont(size: 11); + }).With(d => + { + d.AutoSizeAxes = Axes.Both; + d.AddText($"{first} "); + d.AddUserLink(second, s => s.Font = secondFont.With(size: 11)); + }), + }; + } } } } From 6bf6084ae9c3129d8a5672946e33205e8eabfcd3 Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 19:24:46 +0200 Subject: [PATCH 03/61] fixed according to suggestions --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 14e5831ef9..deb77c27de 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -308,7 +308,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = new[] { getMapper(metadata) }, + Child = getMapper(metadata), }, infoLabelContainer = new FillFlowContainer { @@ -431,10 +431,10 @@ namespace osu.Game.Screens.Select ForceRedraw(); } - private LinkFlowContainer getMapper(BeatmapMetadata metadata) + private Drawable getMapper(BeatmapMetadata metadata) { if (metadata.Author == null) - return new LinkFlowContainer(); + return Empty(); return new LinkFlowContainer(s => { From c73bbf0aa7566c1bf33784caacb91fc786a7a2cc Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 19:24:58 +0200 Subject: [PATCH 04/61] Fixed Tests --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index 7ea6373763..16afc5ace7 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("check version", () => infoWedge.Info.VersionLabel.Current.Value == $"{ruleset.ShortName}Version"); AddAssert("check title", () => infoWedge.Info.TitleLabel.Current.Value == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Current.Value == $"{ruleset.ShortName}Artist"); - AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Current.Value == $"{ruleset.ShortName}Author")); + AddAssert("check author", () => infoWedge.Info.MapperContainer.ChildrenOfType().Any(s => s.Current.Value == $"{ruleset.ShortName}Author")); } private void testInfoLabels(int expectedCount) @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Current.Value)); AddAssert("check default title", () => infoWedge.Info.TitleLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Artist); - AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); + AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.ChildrenOfType().Any()); AddAssert("check no info labels", () => !infoWedge.Info.ChildrenOfType().Any()); } From 625890381f306823600468a8e590241ab88694d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 May 2021 16:47:47 +0900 Subject: [PATCH 05/61] Update `ComboCounter` components to use DI to attach data source --- .../Visual/Gameplay/TestSceneComboCounter.cs | 24 +++++++------------ .../Visual/Gameplay/TestSceneHUDOverlay.cs | 12 ++++++---- .../Gameplay/TestSceneSkinnableHUDOverlay.cs | 20 ++++++---------- .../Screens/Play/HUD/DefaultComboCounter.cs | 7 +++++- .../Screens/Play/HUD/LegacyComboCounter.cs | 6 +++-- .../Screens/Play/HUD/SkinnableComboCounter.cs | 15 +----------- osu.Game/Screens/Play/HUDOverlay.cs | 12 ++++------ osu.Game/Screens/Play/Player.cs | 2 ++ 8 files changed, 41 insertions(+), 57 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneComboCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneComboCounter.cs index d0c2fb5064..b0a0b5189f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneComboCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneComboCounter.cs @@ -4,9 +4,11 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay @@ -17,31 +19,21 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { - AddStep("Create combo counters", () => SetContents(() => - { - var comboCounter = new SkinnableComboCounter(); - comboCounter.Current.Value = 1; - return comboCounter; - })); + AddStep("Create combo counters", () => SetContents(() => new SkinnableComboCounter())); } [Test] public void TestComboCounterIncrementing() { - AddRepeatStep("increase combo", () => - { - foreach (var counter in comboCounters) - counter.Current.Value++; - }, 10); + AddRepeatStep("increase combo", () => scoreProcessor.Combo.Value++, 10); - AddStep("reset combo", () => - { - foreach (var counter in comboCounters) - counter.Current.Value = 0; - }); + AddStep("reset combo", () => scoreProcessor.Combo.Value = 0); } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 3cefb8623f..55c681b605 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; using osuTK.Input; @@ -19,6 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay { private HUDOverlay hudOverlay; + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); @@ -31,9 +35,9 @@ namespace osu.Game.Tests.Visual.Gameplay { createNew(); - AddRepeatStep("increase combo", () => { hudOverlay.ComboCounter.Current.Value++; }, 10); + AddRepeatStep("increase combo", () => { scoreProcessor.Combo.Value++; }, 10); - AddStep("reset combo", () => { hudOverlay.ComboCounter.Current.Value = 0; }); + AddStep("reset combo", () => { scoreProcessor.Combo.Value = 0; }); } [Test] @@ -139,12 +143,12 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create overlay", () => { - hudOverlay = new HUDOverlay(null, null, null, Array.Empty()); + hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); - hudOverlay.ComboCounter.Current.Value = 1; + scoreProcessor.Combo.Value = 1; action?.Invoke(hudOverlay); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index fec1610160..8131c77b4b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -14,6 +14,7 @@ using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; using osuTK.Input; @@ -23,6 +24,9 @@ namespace osu.Game.Tests.Visual.Gameplay { private HUDOverlay hudOverlay; + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + private IEnumerable hudOverlays => CreatedDrawables.OfType(); // best way to check without exposing. @@ -37,17 +41,9 @@ namespace osu.Game.Tests.Visual.Gameplay { createNew(); - AddRepeatStep("increase combo", () => - { - foreach (var hud in hudOverlays) - hud.ComboCounter.Current.Value++; - }, 10); + AddRepeatStep("increase combo", () => scoreProcessor.Combo.Value++, 10); - AddStep("reset combo", () => - { - foreach (var hud in hudOverlays) - hud.ComboCounter.Current.Value = 0; - }); + AddStep("reset combo", () => scoreProcessor.Combo.Value = 0); } [Test] @@ -80,13 +76,11 @@ namespace osu.Game.Tests.Visual.Gameplay { SetContents(() => { - hudOverlay = new HUDOverlay(null, null, null, Array.Empty()); + hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); - hudOverlay.ComboCounter.Current.Value = 1; - action?.Invoke(hudOverlay); return hudOverlay; diff --git a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs index 63e7a88550..d0c26afe5e 100644 --- a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Screens.Play.HUD @@ -24,7 +25,11 @@ namespace osu.Game.Screens.Play.HUD } [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.BlueLighter; + private void load(OsuColour colours, ScoreProcessor scoreProcessor) + { + Colour = colours.BlueLighter; + Current.BindTo(scoreProcessor.Combo); + } protected override void Update() { diff --git a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs index b4604c0d01..58a30aea94 100644 --- a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; using osuTK; @@ -79,7 +80,7 @@ namespace osu.Game.Screens.Play.HUD } [BackgroundDependencyLoader] - private void load() + private void load(ScoreProcessor scoreProcessor) { InternalChildren = new[] { @@ -95,7 +96,8 @@ namespace osu.Game.Screens.Play.HUD }, }; - Current.ValueChanged += combo => updateCount(combo.NewValue == 0); + Current.BindTo(scoreProcessor.Combo); + Current.BindValueChanged(combo => updateCount(combo.NewValue == 0), true); } protected override void LoadComplete() diff --git a/osu.Game/Screens/Play/HUD/SkinnableComboCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableComboCounter.cs index c04c50141a..c62f1460c9 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableComboCounter.cs @@ -1,29 +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.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class SkinnableComboCounter : SkinnableDrawable, IComboCounter + public class SkinnableComboCounter : SkinnableDrawable { - public Bindable Current { get; } = new Bindable(); - public SkinnableComboCounter() : base(new HUDSkinComponent(HUDSkinComponents.ComboCounter), skinComponent => new DefaultComboCounter()) { CentreComponent = false; } - - private IComboCounter skinnedCounter; - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - base.SkinChanged(skin, allowFallback); - - skinnedCounter = Drawable as IComboCounter; - skinnedCounter?.Current.BindTo(Current); - } } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 669c920017..83897c5167 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -34,7 +34,6 @@ namespace osu.Game.Screens.Play public float TopScoringElementsHeight { get; private set; } public readonly KeyCounterDisplay KeyCounter; - public readonly SkinnableComboCounter ComboCounter; public readonly SkinnableScoreCounter ScoreCounter; public readonly SkinnableAccuracyCounter AccuracyCounter; public readonly SkinnableHealthDisplay HealthDisplay; @@ -106,7 +105,7 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), AccuracyCounter = CreateAccuracyCounter(), ScoreCounter = CreateScoreCounter(), - ComboCounter = CreateComboCounter(), + CreateComboCounter(), HitErrorDisplay = CreateHitErrorDisplayOverlay(), } }, @@ -276,13 +275,13 @@ namespace osu.Game.Screens.Play Progress.BindDrawableRuleset(drawableRuleset); } - protected virtual SkinnableAccuracyCounter CreateAccuracyCounter() => new SkinnableAccuracyCounter(); + protected SkinnableAccuracyCounter CreateAccuracyCounter() => new SkinnableAccuracyCounter(); - protected virtual SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter(); + protected SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter(); - protected virtual SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter(); + protected SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter(); - protected virtual SkinnableHealthDisplay CreateHealthDisplay() => new SkinnableHealthDisplay(); + protected SkinnableHealthDisplay CreateHealthDisplay() => new SkinnableHealthDisplay(); protected virtual FailingLayer CreateFailingLayer() => new FailingLayer { @@ -323,7 +322,6 @@ namespace osu.Game.Screens.Play { ScoreCounter?.Current.BindTo(processor.TotalScore); AccuracyCounter?.Current.BindTo(processor.Accuracy); - ComboCounter?.Current.BindTo(processor.Combo); if (HealthDisplay is IHealthDisplay shd) { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 27a4fcc291..c9d7bbf4c1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -202,6 +202,8 @@ namespace osu.Game.Screens.Play ScoreProcessor.ApplyBeatmap(playableBeatmap); ScoreProcessor.Mods.BindTo(Mods); + dependencies.CacheAs(ScoreProcessor); + HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor.ApplyBeatmap(playableBeatmap); From ca4b860920c2bd7f1efe518e65347904ab8fd7a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 May 2021 20:11:24 +0900 Subject: [PATCH 06/61] Move `BindValueChanged` call to `LoadComplete` --- osu.Game/Screens/Play/HUD/LegacyComboCounter.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs index 58a30aea94..0bccbd0338 100644 --- a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs @@ -97,7 +97,6 @@ namespace osu.Game.Screens.Play.HUD }; Current.BindTo(scoreProcessor.Combo); - Current.BindValueChanged(combo => updateCount(combo.NewValue == 0), true); } protected override void LoadComplete() @@ -111,7 +110,7 @@ namespace osu.Game.Screens.Play.HUD popOutCount.Origin = Origin; popOutCount.Anchor = Anchor; - updateCount(false); + Current.BindValueChanged(combo => updateCount(combo.NewValue == 0), true); } private void updateCount(bool rolling) From ee23124bb14409ac6c4833df20b1259ecca888d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 May 2021 15:17:53 +0900 Subject: [PATCH 07/61] Remove no-longer-used interface --- .../Screens/Play/HUD/DefaultComboCounter.cs | 2 +- osu.Game/Screens/Play/HUD/IComboCounter.cs | 19 ------------------- .../Screens/Play/HUD/LegacyComboCounter.cs | 2 +- 3 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/IComboCounter.cs diff --git a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs index d0c26afe5e..5a975c1b80 100644 --- a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class DefaultComboCounter : RollingCounter, IComboCounter + public class DefaultComboCounter : RollingCounter { private readonly Vector2 offset = new Vector2(20, 5); diff --git a/osu.Game/Screens/Play/HUD/IComboCounter.cs b/osu.Game/Screens/Play/HUD/IComboCounter.cs deleted file mode 100644 index ff235bf04e..0000000000 --- a/osu.Game/Screens/Play/HUD/IComboCounter.cs +++ /dev/null @@ -1,19 +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.Framework.Graphics; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// An interface providing a set of methods to update a combo counter. - /// - public interface IComboCounter : IDrawable - { - /// - /// The current combo to be displayed. - /// - Bindable Current { get; } - } -} diff --git a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs index 0bccbd0338..8ecd960de1 100644 --- a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Play.HUD /// /// Uses the 'x' symbol and has a pop-out effect while rolling over. /// - public class LegacyComboCounter : CompositeDrawable, IComboCounter + public class LegacyComboCounter : CompositeDrawable { public Bindable Current { get; } = new BindableInt { MinValue = 0, }; From 39067e6926e0950303e137140dded1f2eb2f5dd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 May 2021 17:19:18 +0900 Subject: [PATCH 08/61] Fix slider input handling potentially being offset after composer area resize Closes https://github.com/ppy/osu/issues/12671. --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 4 ++++ 1 file changed, 4 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 1c3d270c95..6e22c35ab3 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,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; + + // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. + // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. + AlwaysPresent = true; } [BackgroundDependencyLoader] From 9be36230f9bd5825aafc5b5f664480d76bdf43fb Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 6 May 2021 21:43:30 +0900 Subject: [PATCH 09/61] Introduce AutoGenerator subclass for frame based replay generation --- osu.Game/Rulesets/Replays/AutoGenerator.cs | 27 +++++------- .../Rulesets/Replays/FramedAutoGenerator.cs | 44 +++++++++++++++++++ 2 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 osu.Game/Rulesets/Replays/FramedAutoGenerator.cs diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index b3c609f2f4..4bdd5b094d 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Game.Beatmaps; @@ -7,34 +7,27 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Replays { - public abstract class AutoGenerator : IAutoGenerator + public abstract class AutoGenerator { /// - /// Creates the auto replay and returns it. - /// Every subclass of OsuAutoGeneratorBase should implement this! + /// The default duration of a key press in milliseconds. /// - public abstract Replay Generate(); - - #region Parameters + public const double KEY_UP_DELAY = 50; /// - /// The beatmap we're making. + /// The beatmap the autoplay is generated for. /// - protected IBeatmap Beatmap; - - #endregion + protected IBeatmap Beatmap { get; } protected AutoGenerator(IBeatmap beatmap) { Beatmap = beatmap; } - #region Constants - - // Shared amongst all modes - public const double KEY_UP_DELAY = 50; - - #endregion + /// + /// Generate the replay of the autoplay. + /// + public abstract Replay Generate(); protected virtual HitObject GetNextObject(int currentIndex) { diff --git a/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs b/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs new file mode 100644 index 0000000000..091eb00232 --- /dev/null +++ b/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Replays; + +namespace osu.Game.Rulesets.Replays +{ + public abstract class FramedAutoGenerator : AutoGenerator + where TFrame : ReplayFrame + { + /// + /// The replay frames of the autoplay. + /// + protected readonly List Frames = new List(); + + protected TFrame? LastFrame => Frames.Count == 0 ? null : Frames[^1]; + + protected FramedAutoGenerator(IBeatmap beatmap) + : base(beatmap) + { + } + + public sealed override Replay Generate() + { + Frames.Clear(); + GenerateFrames(); + + return new Replay + { + Frames = Frames.OrderBy(frame => frame.Time).Cast().ToList() + }; + } + + /// + /// Generate the replay frames of the autoplay and populate . + /// + protected abstract void GenerateFrames(); + } +} From ea35b72436d6c38a477d3ae3e8dfb11b15653248 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 6 May 2021 22:56:21 +0900 Subject: [PATCH 10/61] Remove unused IAutoGenerator interface --- osu.Game/Rulesets/Replays/IAutoGenerator.cs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 osu.Game/Rulesets/Replays/IAutoGenerator.cs diff --git a/osu.Game/Rulesets/Replays/IAutoGenerator.cs b/osu.Game/Rulesets/Replays/IAutoGenerator.cs deleted file mode 100644 index b1905e2b6f..0000000000 --- a/osu.Game/Rulesets/Replays/IAutoGenerator.cs +++ /dev/null @@ -1,12 +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.Replays; - -namespace osu.Game.Rulesets.Replays -{ - public interface IAutoGenerator - { - Replay Generate(); - } -} From cf39178099c9178e5ef9136bfdabc6dbcdf5cc02 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 6 May 2021 21:53:34 +0900 Subject: [PATCH 11/61] Use FramedAutoGenerator in Taiko, Catch, Mania OsuAutoGenerator is not included in this change because it uses SortedList-like thing --- .../Replays/CatchAutoGenerator.cs | 20 ++++--------------- .../Replays/ManiaAutoGenerator.cs | 15 ++++---------- .../Replays/TaikoAutoGenerator.cs | 14 +++---------- 3 files changed, 11 insertions(+), 38 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index 10230b6b78..2e1e4f7e77 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; @@ -13,26 +12,19 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Catch.Replays { - internal class CatchAutoGenerator : AutoGenerator + internal class CatchAutoGenerator : FramedAutoGenerator { - public const double RELEASE_DELAY = 20; - public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap; public CatchAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - protected Replay Replay; - - private CatchReplayFrame currentFrame; - - public override Replay Generate() + protected override void GenerateFrames() { if (Beatmap.HitObjects.Count == 0) - return Replay; + return; // todo: add support for HT DT const double dash_speed = Catcher.BASE_SPEED; @@ -119,15 +111,11 @@ namespace osu.Game.Rulesets.Catch.Replays } } } - - return Replay; } private void addFrame(double time, float? position = null, bool dashing = false) { - var last = currentFrame; - currentFrame = new CatchReplayFrame(time, position, dashing, last); - Replay.Frames.Add(currentFrame); + Frames.Add(new CatchReplayFrame(time, position, dashing, LastFrame)); } } } diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index ada84dfac2..4fd105025c 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Game.Replays; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; @@ -11,7 +10,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Mania.Replays { - internal class ManiaAutoGenerator : AutoGenerator + internal class ManiaAutoGenerator : FramedAutoGenerator { public const double RELEASE_DELAY = 20; @@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Mania.Replays public ManiaAutoGenerator(ManiaBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); - columnActions = new ManiaAction[Beatmap.TotalColumns]; var normalAction = ManiaAction.Key1; @@ -43,12 +40,10 @@ namespace osu.Game.Rulesets.Mania.Replays } } - protected Replay Replay; - - public override Replay Generate() + protected override void GenerateFrames() { if (Beatmap.HitObjects.Count == 0) - return Replay; + return; var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time); @@ -70,10 +65,8 @@ namespace osu.Game.Rulesets.Mania.Replays } } - Replay.Frames.Add(new ManiaReplayFrame(group.First().Time, actions.ToArray())); + Frames.Add(new ManiaReplayFrame(group.First().Time, actions.ToArray())); } - - return Replay; } private IEnumerable generateActionPoints() diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index fa0134aa94..bd2b7338de 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -2,10 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Taiko.Beatmaps; @@ -13,7 +11,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Taiko.Replays { - public class TaikoAutoGenerator : AutoGenerator + public class TaikoAutoGenerator : FramedAutoGenerator { public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap; @@ -22,16 +20,12 @@ namespace osu.Game.Rulesets.Taiko.Replays public TaikoAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - protected Replay Replay; - protected List Frames => Replay.Frames; - - public override Replay Generate() + protected override void GenerateFrames() { if (Beatmap.HitObjects.Count == 0) - return Replay; + return; bool hitButton = true; @@ -128,8 +122,6 @@ namespace osu.Game.Rulesets.Taiko.Replays hitButton = !hitButton; } - - return Replay; } } } From 95c74c906a33084142a71bd16b58d4063f237bfb Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 6 May 2021 21:57:03 +0900 Subject: [PATCH 12/61] Use FramedAutoGenerator in template projects --- .../Replays/EmptyFreeformAutoGenerator.cs | 12 ++---------- .../Replays/PippidonAutoGenerator.cs | 12 ++---------- .../Replays/EmptyScrollingAutoGenerator.cs | 12 ++---------- .../Replays/PippidonAutoGenerator.cs | 12 ++---------- 4 files changed, 8 insertions(+), 40 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs index 6d8d4215a2..5d61136f54 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs @@ -1,28 +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 System.Collections.Generic; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets.EmptyFreeform.Objects; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.EmptyFreeform.Replays { - public class EmptyFreeformAutoGenerator : AutoGenerator + public class EmptyFreeformAutoGenerator : FramedAutoGenerator { - protected Replay Replay; - protected List Frames => Replay.Frames; - public new Beatmap Beatmap => (Beatmap)base.Beatmap; public EmptyFreeformAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - public override Replay Generate() + protected override void GenerateFrames() { Frames.Add(new EmptyFreeformReplayFrame()); @@ -35,8 +29,6 @@ namespace osu.Game.Rulesets.EmptyFreeform.Replays // todo: add required inputs and extra frames. }); } - - return Replay; } } } diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs index 9c54b82e38..f795d7ef21 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs @@ -1,28 +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 System.Collections.Generic; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets.Pippidon.Objects; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Pippidon.Replays { - public class PippidonAutoGenerator : AutoGenerator + public class PippidonAutoGenerator : FramedAutoGenerator { - protected Replay Replay; - protected List Frames => Replay.Frames; - public new Beatmap Beatmap => (Beatmap)base.Beatmap; public PippidonAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - public override Replay Generate() + protected override void GenerateFrames() { Frames.Add(new PippidonReplayFrame()); @@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays Position = hitObject.Position, }); } - - return Replay; } } } diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs index 7923918842..ab27fd4dcd 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs @@ -1,28 +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 System.Collections.Generic; using osu.Game.Beatmaps; -using osu.Game.Replays; using osu.Game.Rulesets.EmptyScrolling.Objects; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.EmptyScrolling.Replays { - public class EmptyScrollingAutoGenerator : AutoGenerator + public class EmptyScrollingAutoGenerator : FramedAutoGenerator { - protected Replay Replay; - protected List Frames => Replay.Frames; - public new Beatmap Beatmap => (Beatmap)base.Beatmap; public EmptyScrollingAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - public override Replay Generate() + protected override void GenerateFrames() { Frames.Add(new EmptyScrollingReplayFrame()); @@ -34,8 +28,6 @@ namespace osu.Game.Rulesets.EmptyScrolling.Replays // todo: add required inputs and extra frames. }); } - - return Replay; } } } diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs index bd99cdcdbd..df2cfb8731 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs @@ -2,29 +2,23 @@ // 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.Replays; using osu.Game.Rulesets.Pippidon.Objects; using osu.Game.Rulesets.Pippidon.UI; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Pippidon.Replays { - public class PippidonAutoGenerator : AutoGenerator + public class PippidonAutoGenerator : FramedAutoGenerator { - protected Replay Replay; - protected List Frames => Replay.Frames; - public new Beatmap Beatmap => (Beatmap)base.Beatmap; public PippidonAutoGenerator(IBeatmap beatmap) : base(beatmap) { - Replay = new Replay(); } - public override Replay Generate() + protected override void GenerateFrames() { int currentLane = 0; @@ -55,8 +49,6 @@ namespace osu.Game.Rulesets.Pippidon.Replays currentLane = hitObject.Lane; } - - return Replay; } private void addFrame(double time, PippidonAction direction) From 207f7f1e563ce252eb88affc19cdd09544d80212 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 7 May 2021 00:31:12 +0900 Subject: [PATCH 13/61] Rename FramedAutoGenerator -> AutoGenerator --- .../Replays/EmptyFreeformAutoGenerator.cs | 2 +- .../Replays/PippidonAutoGenerator.cs | 2 +- .../Replays/EmptyScrollingAutoGenerator.cs | 2 +- .../Replays/PippidonAutoGenerator.cs | 2 +- .../Replays/CatchAutoGenerator.cs | 2 +- .../Replays/ManiaAutoGenerator.cs | 2 +- .../Replays/TaikoAutoGenerator.cs | 2 +- osu.Game/Rulesets/Replays/AutoGenerator.cs | 36 +++++++++++++++ .../Rulesets/Replays/FramedAutoGenerator.cs | 44 ------------------- 9 files changed, 43 insertions(+), 51 deletions(-) delete mode 100644 osu.Game/Rulesets/Replays/FramedAutoGenerator.cs diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs index 5d61136f54..62f394d1ce 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformAutoGenerator.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.EmptyFreeform.Replays { - public class EmptyFreeformAutoGenerator : FramedAutoGenerator + public class EmptyFreeformAutoGenerator : AutoGenerator { public new Beatmap Beatmap => (Beatmap)base.Beatmap; diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs index f795d7ef21..612288257d 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Pippidon.Replays { - public class PippidonAutoGenerator : FramedAutoGenerator + public class PippidonAutoGenerator : AutoGenerator { public new Beatmap Beatmap => (Beatmap)base.Beatmap; diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs index ab27fd4dcd..1058f756f3 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Replays/EmptyScrollingAutoGenerator.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.EmptyScrolling.Replays { - public class EmptyScrollingAutoGenerator : FramedAutoGenerator + public class EmptyScrollingAutoGenerator : AutoGenerator { public new Beatmap Beatmap => (Beatmap)base.Beatmap; diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs index df2cfb8731..724026273d 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Replays/PippidonAutoGenerator.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Pippidon.Replays { - public class PippidonAutoGenerator : FramedAutoGenerator + public class PippidonAutoGenerator : AutoGenerator { public new Beatmap Beatmap => (Beatmap)base.Beatmap; diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index 2e1e4f7e77..a81703119a 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Catch.Replays { - internal class CatchAutoGenerator : FramedAutoGenerator + internal class CatchAutoGenerator : AutoGenerator { public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap; diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 4fd105025c..517b708691 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Mania.Replays { - internal class ManiaAutoGenerator : FramedAutoGenerator + internal class ManiaAutoGenerator : AutoGenerator { public const double RELEASE_DELAY = 20; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index bd2b7338de..5fd281f9fa 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Taiko.Replays { - public class TaikoAutoGenerator : FramedAutoGenerator + public class TaikoAutoGenerator : AutoGenerator { public new TaikoBeatmap Beatmap => (TaikoBeatmap)base.Beatmap; diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index 4bdd5b094d..6ce857b14b 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -1,6 +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.Linq; +using JetBrains.Annotations; using osu.Game.Beatmaps; using osu.Game.Replays; using osu.Game.Rulesets.Objects; @@ -37,4 +40,37 @@ namespace osu.Game.Rulesets.Replays return Beatmap.HitObjects[currentIndex + 1]; } } + + public abstract class AutoGenerator : AutoGenerator + where TFrame : ReplayFrame + { + /// + /// The replay frames of the autoplay. + /// + protected readonly List Frames = new List(); + + [CanBeNull] + protected TFrame LastFrame => Frames.Count == 0 ? null : Frames[^1]; + + protected AutoGenerator(IBeatmap beatmap) + : base(beatmap) + { + } + + public sealed override Replay Generate() + { + Frames.Clear(); + GenerateFrames(); + + return new Replay + { + Frames = Frames.OrderBy(frame => frame.Time).Cast().ToList() + }; + } + + /// + /// Generate the replay frames of the autoplay and populate . + /// + protected abstract void GenerateFrames(); + } } diff --git a/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs b/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs deleted file mode 100644 index 091eb00232..0000000000 --- a/osu.Game/Rulesets/Replays/FramedAutoGenerator.cs +++ /dev/null @@ -1,44 +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 enable - -using System.Collections.Generic; -using System.Linq; -using osu.Game.Beatmaps; -using osu.Game.Replays; - -namespace osu.Game.Rulesets.Replays -{ - public abstract class FramedAutoGenerator : AutoGenerator - where TFrame : ReplayFrame - { - /// - /// The replay frames of the autoplay. - /// - protected readonly List Frames = new List(); - - protected TFrame? LastFrame => Frames.Count == 0 ? null : Frames[^1]; - - protected FramedAutoGenerator(IBeatmap beatmap) - : base(beatmap) - { - } - - public sealed override Replay Generate() - { - Frames.Clear(); - GenerateFrames(); - - return new Replay - { - Frames = Frames.OrderBy(frame => frame.Time).Cast().ToList() - }; - } - - /// - /// Generate the replay frames of the autoplay and populate . - /// - protected abstract void GenerateFrames(); - } -} From 54fe10c82a855a16c88f8781a9ae12dc42df7b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 10:36:03 +0900 Subject: [PATCH 14/61] Refactor `SliderSelectionBlueprint` to not reference blueprint pieces for input handling --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 6 ------ .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 ++-- 2 files changed, 2 insertions(+), 8 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 6e22c35ab3..ece9c7a757 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,10 +26,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; - - // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. - // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. - AlwaysPresent = true; } [BackgroundDependencyLoader] @@ -54,7 +50,5 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } public void RecyclePath() => body.RecyclePath(); - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 88fcb1e715..32d2fba25e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,10 +240,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); + public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; + slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); } From 84da24700204724cde9a8b90506b078add49c964 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 05:32:55 +0300 Subject: [PATCH 15/61] Fix editor clock using the wrong beatmap track on creation --- osu.Game/Screens/Edit/Editor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index da0e9ebbaf..138d8cfaff 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -145,7 +145,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - UpdateClockSource(); + updateClockSource(loadableBeatmap); dependencies.CacheAs(clock); AddInternal(clock); @@ -308,9 +308,11 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() + public void UpdateClockSource() => updateClockSource(Beatmap.Value); + + private void updateClockSource(WorkingBeatmap beatmap) { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); clock.ChangeSource(sourceClock); } From 539643c72b390b1c40b8fb8340b37f33ef91d7d5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:18:43 +0300 Subject: [PATCH 16/61] Set loadable beatmap track to clock immediately in BDL This reverts commit 84da24700204724cde9a8b90506b078add49c964. Use loadable beatmap track for clock directly in BDL --- osu.Game/Screens/Edit/Editor.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 138d8cfaff..a4c331c4e0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -144,8 +144,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - - updateClockSource(loadableBeatmap); + clock.ChangeSource(loadableBeatmap.Track); dependencies.CacheAs(clock); AddInternal(clock); @@ -308,11 +307,9 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() => updateClockSource(Beatmap.Value); - - private void updateClockSource(WorkingBeatmap beatmap) + public void UpdateClockSource() { - var sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); clock.ChangeSource(sourceClock); } From f9d99a98826525b58d8a076f772da6a9a77329ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:25:14 +0300 Subject: [PATCH 17/61] Mark `WorkingBeatmap.Track` as not null --- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index e0eeaf6db0..bef258753e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -298,6 +298,7 @@ namespace osu.Game.Beatmaps /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. /// + [NotNull] public Track Track { get From 71547bece0dcd99cfbe6ba95bd2e42066b6eb686 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:43:06 +0300 Subject: [PATCH 18/61] Remove any null-coalescing/conditionals in `WorkingBeatmap.Track` usages --- osu.Game/Screens/Edit/Editor.cs | 9 ++------- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a4c331c4e0..434683a016 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,7 +17,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -307,11 +306,7 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() - { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock.ChangeSource(sourceClock); - } + public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); protected void Save() { @@ -582,7 +577,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + Beatmap.Value.Track.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 79cfee8518..34393fba7d 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(e.NewValue.Track); Clock.ProcessFrame(); } From 37f44d2e37602ec557ed7fda6ca7afced0bfec81 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 08:27:56 +0300 Subject: [PATCH 19/61] Revert wrong not-null track changes This reverts commit f9d99a98826525b58d8a076f772da6a9a77329ec. This reverts commit 71547bece0dcd99cfbe6ba95bd2e42066b6eb686. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 - osu.Game/Screens/Edit/Editor.cs | 9 +++++++-- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bef258753e..e0eeaf6db0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -298,7 +298,6 @@ namespace osu.Game.Beatmaps /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. /// - [NotNull] public Track Track { get diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 434683a016..a4c331c4e0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,6 +17,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -306,7 +307,11 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); + public void UpdateClockSource() + { + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + clock.ChangeSource(sourceClock); + } protected void Save() { @@ -577,7 +582,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track.Stop(); + Beatmap.Value.Track?.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 34393fba7d..79cfee8518 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(e.NewValue.Track); + Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } From b1134c3857980e5f473dc3ba3f57d1ab7bdcabdb Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 08:30:50 +0300 Subject: [PATCH 20/61] Guard against potentially null track if ever --- 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 a4c331c4e0..78d5c24108 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -144,7 +144,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(loadableBeatmap.Track); + clock.ChangeSource((IAdjustableClock)loadableBeatmap.Track ?? new StopwatchClock()); dependencies.CacheAs(clock); AddInternal(clock); From 7c4e54a1d43990996e015affd03911514dc18952 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 09:53:54 +0300 Subject: [PATCH 21/61] Unrevert null-colaescing/conditionals removal --- osu.Game/Screens/Edit/Editor.cs | 8 ++------ osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 78d5c24108..50dcb84235 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -307,11 +307,7 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() - { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock.ChangeSource(sourceClock); - } + public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); protected void Save() { @@ -582,7 +578,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + Beatmap.Value.Track.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 79cfee8518..34393fba7d 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(e.NewValue.Track); Clock.ProcessFrame(); } From fc2a527e9d419040697cd4e075c7ae04d1cd2c82 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 09:54:58 +0300 Subject: [PATCH 22/61] Revert "Guard against potentially null track if ever" This reverts commit b1134c3857980e5f473dc3ba3f57d1ab7bdcabdb. --- osu.Game/Screens/Edit/Editor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 50dcb84235..434683a016 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,7 +17,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -144,7 +143,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - clock.ChangeSource((IAdjustableClock)loadableBeatmap.Track ?? new StopwatchClock()); + clock.ChangeSource(loadableBeatmap.Track); dependencies.CacheAs(clock); AddInternal(clock); From a2e4fb5b6b0cc7cd97fa439a9e2e1b13dcb6f10e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 16:10:57 +0900 Subject: [PATCH 23/61] Update `ScoreCounter` components to bind outwards --- .../TestSceneSkinnableScoreCounter.cs | 26 ++++------ .../Graphics/UserInterface/ScoreCounter.cs | 3 +- .../Screens/Play/HUD/DefaultScoreCounter.cs | 3 +- .../Screens/Play/HUD/GameplayScoreCounter.cs | 46 ++++++++++++++++++ osu.Game/Screens/Play/HUD/IScoreCounter.cs | 25 ---------- .../Screens/Play/HUD/SkinnableScoreCounter.cs | 47 +------------------ osu.Game/Screens/Play/HUDOverlay.cs | 1 - osu.Game/Skinning/LegacyScoreCounter.cs | 4 +- 8 files changed, 60 insertions(+), 95 deletions(-) create mode 100644 osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs delete mode 100644 osu.Game/Screens/Play/HUD/IScoreCounter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs index e212ceeba7..4f2183711e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs @@ -4,10 +4,12 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay @@ -18,37 +20,27 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { - AddStep("Create combo counters", () => SetContents(() => - { - var comboCounter = new SkinnableScoreCounter(); - comboCounter.Current.Value = 1; - return comboCounter; - })); + AddStep("Create score counters", () => SetContents(() => new SkinnableScoreCounter())); } [Test] public void TestScoreCounterIncrementing() { - AddStep(@"Reset all", delegate - { - foreach (var s in scoreCounters) - s.Current.Value = 0; - }); + AddStep(@"Reset all", () => scoreProcessor.TotalScore.Value = 0); - AddStep(@"Hit! :D", delegate - { - foreach (var s in scoreCounters) - s.Current.Value += 300; - }); + AddStep(@"Hit! :D", () => scoreProcessor.TotalScore.Value += 300); } [Test] public void TestVeryLargeScore() { - AddStep("set large score", () => scoreCounters.ForEach(counter => counter.Current.Value = 1_000_000_000)); + AddStep("set large score", () => scoreCounters.ForEach(counter => scoreProcessor.TotalScore.Value = 1_000_000_000)); } } } diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index d75e49a4ce..5747c846eb 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -4,11 +4,10 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Screens.Play.HUD; namespace osu.Game.Graphics.UserInterface { - public abstract class ScoreCounter : RollingCounter, IScoreCounter + public abstract class ScoreCounter : RollingCounter { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs index 1dcfe2e067..84db605d53 100644 --- a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs @@ -4,11 +4,10 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Play.HUD { - public class DefaultScoreCounter : ScoreCounter + public class DefaultScoreCounter : GameplayScoreCounter { public DefaultScoreCounter() : base(6) diff --git a/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs new file mode 100644 index 0000000000..e09630d2c4 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.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; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD +{ + public abstract class GameplayScoreCounter : ScoreCounter + { + private Bindable scoreDisplayMode; + + protected GameplayScoreCounter(int leading = 0, bool useCommaSeparator = false) + : base(leading, useCommaSeparator) + { + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, ScoreProcessor scoreProcessor) + { + scoreDisplayMode = config.GetBindable(OsuSetting.ScoreDisplayMode); + scoreDisplayMode.BindValueChanged(scoreMode => + { + switch (scoreMode.NewValue) + { + case ScoringMode.Standardised: + RequiredDisplayDigits.Value = 6; + break; + + case ScoringMode.Classic: + RequiredDisplayDigits.Value = 8; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(scoreMode)); + } + }, true); + + Current.BindTo(scoreProcessor.TotalScore); + } + } +} diff --git a/osu.Game/Screens/Play/HUD/IScoreCounter.cs b/osu.Game/Screens/Play/HUD/IScoreCounter.cs deleted file mode 100644 index 7f5e81d5ef..0000000000 --- a/osu.Game/Screens/Play/HUD/IScoreCounter.cs +++ /dev/null @@ -1,25 +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.Framework.Graphics; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// An interface providing a set of methods to update a score counter. - /// - public interface IScoreCounter : IDrawable - { - /// - /// The current score to be displayed. - /// - Bindable Current { get; } - - /// - /// The number of digits required to display most sane scores. - /// This may be exceeded in very rare cases, but is useful to pad or space the display to avoid it jumping around. - /// - Bindable RequiredDisplayDigits { get; } - } -} diff --git a/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs index b46f5684b1..cc9a712e97 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs @@ -1,61 +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; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Game.Configuration; -using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class SkinnableScoreCounter : SkinnableDrawable, IScoreCounter + public class SkinnableScoreCounter : SkinnableDrawable { - public Bindable Current { get; } = new Bindable(); - - private Bindable scoreDisplayMode; - - public Bindable RequiredDisplayDigits { get; } = new Bindable(); - public SkinnableScoreCounter() : base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter()) { CentreComponent = false; } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - scoreDisplayMode = config.GetBindable(OsuSetting.ScoreDisplayMode); - scoreDisplayMode.BindValueChanged(scoreMode => - { - switch (scoreMode.NewValue) - { - case ScoringMode.Standardised: - RequiredDisplayDigits.Value = 6; - break; - - case ScoringMode.Classic: - RequiredDisplayDigits.Value = 8; - break; - - default: - throw new ArgumentOutOfRangeException(nameof(scoreMode)); - } - }, true); - } - - private IScoreCounter skinnedCounter; - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - base.SkinChanged(skin, allowFallback); - - skinnedCounter = Drawable as IScoreCounter; - - skinnedCounter?.Current.BindTo(Current); - skinnedCounter?.RequiredDisplayDigits.BindTo(RequiredDisplayDigits); - } } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 83897c5167..c887fb78e0 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -320,7 +320,6 @@ namespace osu.Game.Screens.Play protected virtual void BindScoreProcessor(ScoreProcessor processor) { - ScoreCounter?.Current.BindTo(processor.TotalScore); AccuracyCounter?.Current.BindTo(processor.Accuracy); if (HealthDisplay is IHealthDisplay shd) diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index 1d330ef495..e385caf304 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.cs @@ -4,12 +4,12 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Skinning { - public class LegacyScoreCounter : ScoreCounter + public class LegacyScoreCounter : GameplayScoreCounter { private readonly ISkin skin; From ad398165a2d38870173df9b82034691d8c9c8d4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 16:26:54 +0900 Subject: [PATCH 24/61] Update `AccuracyCounter` components to use DI to attach data source --- .../TestSceneSkinnableAccuracyCounter.cs | 26 ++++++------------- .../Play/HUD/DefaultAccuracyCounter.cs | 3 +-- .../Play/HUD/GameplayAccuracyCounter.cs | 18 +++++++++++++ osu.Game/Screens/Play/HUD/IAccuracyCounter.cs | 19 -------------- .../Play/HUD/SkinnableAccuracyCounter.cs | 12 +-------- osu.Game/Skinning/LegacyAccuracyCounter.cs | 3 +-- 6 files changed, 29 insertions(+), 52 deletions(-) create mode 100644 osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs delete mode 100644 osu.Game/Screens/Play/HUD/IAccuracyCounter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs index 709929dcb0..34356184a2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs @@ -4,9 +4,11 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay @@ -17,33 +19,21 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { - AddStep("Create combo counters", () => SetContents(() => - { - var accuracyCounter = new SkinnableAccuracyCounter(); - - accuracyCounter.Current.Value = 1; - - return accuracyCounter; - })); + AddStep("Create combo counters", () => SetContents(() => new SkinnableAccuracyCounter())); } [Test] public void TestChangingAccuracy() { - AddStep(@"Reset all", delegate - { - foreach (var s in accuracyCounters) - s.Current.Value = 1; - }); + AddStep(@"Reset all", () => scoreProcessor.Accuracy.Value = 1); - AddStep(@"Hit! :D", delegate - { - foreach (var s in accuracyCounters) - s.Current.Value -= 0.023f; - }); + AddStep(@"Hit! :D", () => scoreProcessor.Accuracy.Value -= 0.23); } } } diff --git a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs index d5d8ec570a..be1a4ad6b3 100644 --- a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs @@ -4,12 +4,11 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; using osuTK; namespace osu.Game.Screens.Play.HUD { - public class DefaultAccuracyCounter : PercentageCounter, IAccuracyCounter + public class DefaultAccuracyCounter : GameplayAccuracyCounter { private readonly Vector2 offset = new Vector2(-20, 5); diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs new file mode 100644 index 0000000000..7a63084812 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.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.Framework.Allocation; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD +{ + public abstract class GameplayAccuracyCounter : PercentageCounter + { + [BackgroundDependencyLoader] + private void load(ScoreProcessor scoreProcessor) + { + Current.BindTo(scoreProcessor.Accuracy); + } + } +} diff --git a/osu.Game/Screens/Play/HUD/IAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/IAccuracyCounter.cs deleted file mode 100644 index 0199250a08..0000000000 --- a/osu.Game/Screens/Play/HUD/IAccuracyCounter.cs +++ /dev/null @@ -1,19 +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.Framework.Graphics; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// An interface providing a set of methods to update a accuracy counter. - /// - public interface IAccuracyCounter : IDrawable - { - /// - /// The current accuracy to be displayed. - /// - Bindable Current { get; } - } -} diff --git a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs index 76c9c30813..17c2493d2d 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs @@ -6,7 +6,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class SkinnableAccuracyCounter : SkinnableDrawable, IAccuracyCounter + public class SkinnableAccuracyCounter : SkinnableDrawable { public Bindable Current { get; } = new Bindable(); @@ -15,15 +15,5 @@ namespace osu.Game.Screens.Play.HUD { CentreComponent = false; } - - private IAccuracyCounter skinnedCounter; - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - base.SkinChanged(skin, allowFallback); - - skinnedCounter = Drawable as IAccuracyCounter; - skinnedCounter?.Current.BindTo(Current); - } } } diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index 7d6f1dc916..638faa8f2b 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -4,14 +4,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Skinning { - public class LegacyAccuracyCounter : PercentageCounter, IAccuracyCounter + public class LegacyAccuracyCounter : GameplayAccuracyCounter { private readonly ISkin skin; From 9d27b11e499e634cf3276b1023bb8ac9db9cdf18 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:10:31 +0900 Subject: [PATCH 25/61] Update skin editor test scene to cache a `ScoreProcessor` --- .../Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 086bcb19c3..2424d24bc6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -2,6 +2,7 @@ // 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.Testing; @@ -17,6 +18,9 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene { + [Cached] + private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { @@ -28,8 +32,6 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(ruleset.RulesetInfo); var beatmap = working.GetPlayableBeatmap(ruleset.RulesetInfo); - ScoreProcessor scoreProcessor = new ScoreProcessor(); - var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap); var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty()) @@ -40,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); - hudOverlay.ComboCounter.Current.Value = 1; + scoreProcessor.Combo.Value = 1; return new Container { From 755588258e90883f22a89cee219d6e44373b5887 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 16:56:24 +0900 Subject: [PATCH 26/61] Update `HealthDisplay` components to use DI to attach data source --- .../Visual/Gameplay/TestSceneFailingLayer.cs | 35 ++++++++++++++++--- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 5 ++- .../TestSceneSkinEditorMultipleSkins.cs | 3 +- .../Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- .../TestSceneSkinnableHealthDisplay.cs | 21 ++++++----- .../Screens/Play/HUD/DefaultHealthDisplay.cs | 2 +- osu.Game/Screens/Play/HUD/FailingLayer.cs | 11 +----- osu.Game/Screens/Play/HUD/HealthDisplay.cs | 33 ++++++++++++----- osu.Game/Screens/Play/HUD/IHealthDisplay.cs | 26 -------------- .../Play/HUD/SkinnableHealthDisplay.cs | 15 +------- osu.Game/Screens/Play/HUDOverlay.cs | 22 +----------- osu.Game/Screens/Play/Player.cs | 4 ++- osu.Game/Skinning/LegacyHealthDisplay.cs | 12 ++----- 13 files changed, 81 insertions(+), 110 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/IHealthDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs index 5a1a9d3d87..e426726def 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets.Scoring; @@ -22,22 +23,30 @@ namespace osu.Game.Tests.Visual.Gameplay [SetUpSteps] public void SetUpSteps() + { + } + + private void create(HealthProcessor healthProcessor) { AddStep("create layer", () => { - Child = layer = new FailingLayer(); - layer.BindHealthProcessor(new DrainingHealthProcessor(1)); + Child = new HealthProcessorContainer(healthProcessor) + { + Child = layer = new FailingLayer() + }; + layer.ShowHealth.BindTo(showHealth); }); AddStep("show health", () => showHealth.Value = true); AddStep("enable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true)); - AddUntilStep("layer is visible", () => layer.IsPresent); } [Test] public void TestLayerFading() { + create(new DrainingHealthProcessor(1)); + AddSliderStep("current health", 0.0, 1.0, 1.0, val => { if (layer != null) @@ -53,6 +62,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerDisabledViaConfig() { + create(new DrainingHealthProcessor(1)); + AddUntilStep("layer is visible", () => layer.IsPresent); AddStep("disable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, false)); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); AddUntilStep("layer is not visible", () => !layer.IsPresent); @@ -61,7 +72,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerVisibilityWithAccumulatingProcessor() { - AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new AccumulatingHealthProcessor(1))); + create(new AccumulatingHealthProcessor(1)); + AddUntilStep("layer is not visible", () => !layer.IsPresent); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); AddUntilStep("layer is not visible", () => !layer.IsPresent); } @@ -69,7 +81,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerVisibilityWithDrainingProcessor() { - AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new DrainingHealthProcessor(1))); + create(new DrainingHealthProcessor(1)); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); AddWaitStep("wait for potential fade", 10); AddAssert("layer is still visible", () => layer.IsPresent); @@ -78,6 +90,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerVisibilityWithDifferentOptions() { + create(new DrainingHealthProcessor(1)); + AddStep("set health to 0.10", () => layer.Current.Value = 0.1); AddStep("don't show health", () => showHealth.Value = false); @@ -96,5 +110,16 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("enable FadePlayfieldWhenHealthLow", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, true)); AddUntilStep("layer fade is visible", () => layer.IsPresent); } + + private class HealthProcessorContainer : Container + { + [Cached(typeof(HealthProcessor))] + private readonly HealthProcessor healthProcessor; + + public HealthProcessorContainer(HealthProcessor healthProcessor) + { + this.healthProcessor = healthProcessor; + } + } } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 55c681b605..a451df026b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -23,6 +23,9 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [Cached] + private HealthProcessor healthProcessor = new DrainingHealthProcessor(1); + // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); @@ -143,7 +146,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create overlay", () => { - hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty()); + hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 086bcb19c3..270216564f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Gameplay var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap); - var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty()) + var hudOverlay = new HUDOverlay(scoreProcessor, drawableRuleset, Array.Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -40,7 +40,6 @@ namespace osu.Game.Tests.Visual.Gameplay // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); - hudOverlay.ComboCounter.Current.Value = 1; return new Container { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 8131c77b4b..12ce20f58e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Gameplay { SetContents(() => { - hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty()); + hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index 5bac8582d7..f06236d0a8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -4,11 +4,13 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay @@ -19,6 +21,9 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); + [Cached] + private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); + [SetUpSteps] public void SetUpSteps() { @@ -28,8 +33,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); AddStep(@"Reset all", delegate { - foreach (var s in healthDisplays) - s.Current.Value = 1; + healthProcessor.Health.Value = 1; }); } @@ -38,23 +42,18 @@ namespace osu.Game.Tests.Visual.Gameplay { AddRepeatStep(@"decrease hp", delegate { - foreach (var healthDisplay in healthDisplays) - healthDisplay.Current.Value -= 0.08f; + healthProcessor.Health.Value = 0.08f; }, 10); AddRepeatStep(@"increase hp without flash", delegate { - foreach (var healthDisplay in healthDisplays) - healthDisplay.Current.Value += 0.1f; + healthProcessor.Health.Value = 0.1f; }, 3); AddRepeatStep(@"increase hp with flash", delegate { - foreach (var healthDisplay in healthDisplays) - { - healthDisplay.Current.Value += 0.1f; - healthDisplay.Flash(new JudgementResult(null, new OsuJudgement())); - } + healthProcessor.Health.Value = 0.1f; + healthProcessor.ApplyResult(new JudgementResult(null, new OsuJudgement())); }, 3); } } diff --git a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs index e3cd71691d..27f81467cb 100644 --- a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play.HUD GlowColour = colours.BlueDarker; } - public override void Flash(JudgementResult result) => Scheduler.AddOnce(flash); + protected override void Flash(JudgementResult result) => Scheduler.AddOnce(flash); private void flash() { diff --git a/osu.Game/Screens/Play/HUD/FailingLayer.cs b/osu.Game/Screens/Play/HUD/FailingLayer.cs index 847b8a53cf..e071337f34 100644 --- a/osu.Game/Screens/Play/HUD/FailingLayer.cs +++ b/osu.Game/Screens/Play/HUD/FailingLayer.cs @@ -39,7 +39,6 @@ namespace osu.Game.Screens.Play.HUD private readonly Container boxes; private Bindable fadePlayfieldWhenHealthLow; - private HealthProcessor healthProcessor; public FailingLayer() { @@ -88,18 +87,10 @@ namespace osu.Game.Screens.Play.HUD updateState(); } - public override void BindHealthProcessor(HealthProcessor processor) - { - base.BindHealthProcessor(processor); - - healthProcessor = processor; - updateState(); - } - private void updateState() { // Don't display ever if the ruleset is not using a draining health display. - var showLayer = healthProcessor is DrainingHealthProcessor && fadePlayfieldWhenHealthLow.Value && ShowHealth.Value; + var showLayer = HealthProcessor is DrainingHealthProcessor && fadePlayfieldWhenHealthLow.Value && ShowHealth.Value; this.FadeTo(showLayer ? 1 : 0, fade_time, Easing.OutQuint); } diff --git a/osu.Game/Screens/Play/HUD/HealthDisplay.cs b/osu.Game/Screens/Play/HUD/HealthDisplay.cs index 5c43e00192..2292f64989 100644 --- a/osu.Game/Screens/Play/HUD/HealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HealthDisplay.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Judgements; @@ -11,26 +12,42 @@ namespace osu.Game.Screens.Play.HUD { /// /// A container for components displaying the current player health. - /// Gets bound automatically to the when inserted to hierarchy. + /// Gets bound automatically to the when inserted to hierarchy. /// - public abstract class HealthDisplay : Container, IHealthDisplay + public abstract class HealthDisplay : Container { + [Resolved] + protected HealthProcessor HealthProcessor { get; private set; } + public Bindable Current { get; } = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; - public virtual void Flash(JudgementResult result) + protected virtual void Flash(JudgementResult result) { } - /// - /// Bind the tracked fields of to this health display. - /// - public virtual void BindHealthProcessor(HealthProcessor processor) + [BackgroundDependencyLoader] + private void load() { - Current.BindTo(processor.Health); + Current.BindTo(HealthProcessor.Health); + + HealthProcessor.NewJudgement += onNewJudgement; + } + + private void onNewJudgement(JudgementResult judgement) + { + if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit) Flash(judgement); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (HealthProcessor != null) + HealthProcessor.NewJudgement -= onNewJudgement; } } } diff --git a/osu.Game/Screens/Play/HUD/IHealthDisplay.cs b/osu.Game/Screens/Play/HUD/IHealthDisplay.cs deleted file mode 100644 index b1a64bd844..0000000000 --- a/osu.Game/Screens/Play/HUD/IHealthDisplay.cs +++ /dev/null @@ -1,26 +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.Framework.Graphics; -using osu.Game.Rulesets.Judgements; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// An interface providing a set of methods to update a health display. - /// - public interface IHealthDisplay : IDrawable - { - /// - /// The current health to be displayed. - /// - Bindable Current { get; } - - /// - /// Flash the display for a specified result type. - /// - /// The result type. - void Flash(JudgementResult result); - } -} diff --git a/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs b/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs index 1f91f5e50f..ef0affa417 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs @@ -3,13 +3,12 @@ using System; using osu.Framework.Bindables; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class SkinnableHealthDisplay : SkinnableDrawable, IHealthDisplay + public class SkinnableHealthDisplay : SkinnableDrawable { public Bindable Current { get; } = new BindableDouble(1) { @@ -17,8 +16,6 @@ namespace osu.Game.Screens.Play.HUD MaxValue = 1 }; - public void Flash(JudgementResult result) => skinnedCounter?.Flash(result); - private HealthProcessor processor; public void BindHealthProcessor(HealthProcessor processor) @@ -36,15 +33,5 @@ namespace osu.Game.Screens.Play.HUD { CentreComponent = false; } - - private IHealthDisplay skinnedCounter; - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - base.SkinChanged(skin, allowFallback); - - skinnedCounter = Drawable as IHealthDisplay; - skinnedCounter?.Current.BindTo(Current); - } } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 83897c5167..31a6bc7678 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -47,7 +47,6 @@ namespace osu.Game.Screens.Play public Bindable ShowHealthbar = new Bindable(true); private readonly ScoreProcessor scoreProcessor; - private readonly HealthProcessor healthProcessor; private readonly DrawableRuleset drawableRuleset; private readonly IReadOnlyList mods; @@ -75,10 +74,9 @@ namespace osu.Game.Screens.Play private IEnumerable hideTargets => new Drawable[] { visibilityContainer, KeyCounter, topRightElements }; - public HUDOverlay(ScoreProcessor scoreProcessor, HealthProcessor healthProcessor, DrawableRuleset drawableRuleset, IReadOnlyList mods) + public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList mods) { this.scoreProcessor = scoreProcessor; - this.healthProcessor = healthProcessor; this.drawableRuleset = drawableRuleset; this.mods = mods; @@ -161,9 +159,6 @@ namespace osu.Game.Screens.Play if (scoreProcessor != null) BindScoreProcessor(scoreProcessor); - if (healthProcessor != null) - BindHealthProcessor(healthProcessor); - if (drawableRuleset != null) { BindDrawableRuleset(drawableRuleset); @@ -322,21 +317,6 @@ namespace osu.Game.Screens.Play { ScoreCounter?.Current.BindTo(processor.TotalScore); AccuracyCounter?.Current.BindTo(processor.Accuracy); - - if (HealthDisplay is IHealthDisplay shd) - { - processor.NewJudgement += judgement => - { - if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit) - shd.Flash(judgement); - }; - } - } - - protected virtual void BindHealthProcessor(HealthProcessor processor) - { - HealthDisplay?.BindHealthProcessor(processor); - FailingLayer?.BindHealthProcessor(processor); } public bool OnPressed(GlobalAction action) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 951ce334f6..1538899281 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -208,6 +208,8 @@ namespace osu.Game.Screens.Play HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor.ApplyBeatmap(playableBeatmap); + dependencies.CacheAs(HealthProcessor); + if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); @@ -343,7 +345,7 @@ namespace osu.Game.Screens.Play // display the cursor above some HUD elements. DrawableRuleset.Cursor?.CreateProxy() ?? new Container(), DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(), - HUDOverlay = new HUDOverlay(ScoreProcessor, HealthProcessor, DrawableRuleset, Mods.Value) + HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value) { HoldToQuit = { diff --git a/osu.Game/Skinning/LegacyHealthDisplay.cs b/osu.Game/Skinning/LegacyHealthDisplay.cs index 2e29abf453..c1979efbc2 100644 --- a/osu.Game/Skinning/LegacyHealthDisplay.cs +++ b/osu.Game/Skinning/LegacyHealthDisplay.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Skinning { - public class LegacyHealthDisplay : CompositeDrawable, IHealthDisplay, ISkinnableComponent + public class LegacyHealthDisplay : HealthDisplay { private const double epic_cutoff = 0.5; @@ -28,12 +28,6 @@ namespace osu.Game.Skinning private bool isNewStyle; - public Bindable Current { get; } = new BindableDouble(1) - { - MinValue = 0, - MaxValue = 1 - }; - public LegacyHealthDisplay(Skin skin) { this.skin = skin; @@ -83,7 +77,7 @@ namespace osu.Game.Skinning marker.Position = fill.Position + new Vector2(fill.DrawWidth, isNewStyle ? fill.DrawHeight / 2 : 0); } - public void Flash(JudgementResult result) => marker.Flash(result); + protected override void Flash(JudgementResult result) => marker.Flash(result); private static Texture getTexture(Skin skin, string name) => skin.GetTexture($"scorebar-{name}"); @@ -254,7 +248,7 @@ namespace osu.Game.Skinning Main.ScaleTo(1.4f).Then().ScaleTo(1, 200, Easing.Out); } - public class LegacyHealthPiece : CompositeDrawable, IHealthDisplay + public class LegacyHealthPiece : CompositeDrawable { public Bindable Current { get; } = new Bindable(); From 84a4ff333eec332a3c5dbd9b167f15b17fc6db7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:10:31 +0900 Subject: [PATCH 27/61] Update skin editor test scene to cache a `ScoreProcessor` --- .../Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 270216564f..d50d4aa920 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -2,6 +2,7 @@ // 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.Testing; @@ -17,6 +18,9 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene { + [Cached] + private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { @@ -28,8 +32,6 @@ namespace osu.Game.Tests.Visual.Gameplay var working = CreateWorkingBeatmap(ruleset.RulesetInfo); var beatmap = working.GetPlayableBeatmap(ruleset.RulesetInfo); - ScoreProcessor scoreProcessor = new ScoreProcessor(); - var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap); var hudOverlay = new HUDOverlay(scoreProcessor, drawableRuleset, Array.Empty()) @@ -40,6 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); + scoreProcessor.Combo.Value = 1; return new Container { From 8e78cac05826b2e01959e3971a8043d0f53cf9df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:31:29 +0900 Subject: [PATCH 28/61] Fix `HealthProcessor` cached as derived type in test --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index a451df026b..accb2ba1d9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(); - [Cached] + [Cached(typeof(HealthProcessor))] private HealthProcessor healthProcessor = new DrainingHealthProcessor(1); // best way to check without exposing. From 6c255a05726faed8e6244ded666cee31966a5f72 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:47:33 +0900 Subject: [PATCH 29/61] Fix drain start time being weirdly incorrect --- osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs | 8 ++++---- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs index e426726def..99facb2731 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerFading() { - create(new DrainingHealthProcessor(1)); + create(new DrainingHealthProcessor(0)); AddSliderStep("current health", 0.0, 1.0, 1.0, val => { @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerDisabledViaConfig() { - create(new DrainingHealthProcessor(1)); + create(new DrainingHealthProcessor(0)); AddUntilStep("layer is visible", () => layer.IsPresent); AddStep("disable layer", () => config.SetValue(OsuSetting.FadePlayfieldWhenHealthLow, false)); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); @@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerVisibilityWithDrainingProcessor() { - create(new DrainingHealthProcessor(1)); + create(new DrainingHealthProcessor(0)); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); AddWaitStep("wait for potential fade", 10); AddAssert("layer is still visible", () => layer.IsPresent); @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLayerVisibilityWithDifferentOptions() { - create(new DrainingHealthProcessor(1)); + create(new DrainingHealthProcessor(0)); AddStep("set health to 0.10", () => layer.Current.Value = 0.1); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index accb2ba1d9..861d4a4f7f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Gameplay private ScoreProcessor scoreProcessor = new ScoreProcessor(); [Cached(typeof(HealthProcessor))] - private HealthProcessor healthProcessor = new DrainingHealthProcessor(1); + private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; From 3044b1c432621823fb9bd25b5190b38988ff8696 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:47:38 +0900 Subject: [PATCH 30/61] Add missing cache rules --- .../Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs | 3 +++ .../Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 3 +++ .../Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index d50d4aa920..ac5599cc27 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -21,6 +21,9 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached] private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(); + [Cached(typeof(HealthProcessor))] + private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); + [SetUpSteps] public void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 12ce20f58e..7a960a09fc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -27,6 +27,9 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [Cached(typeof(HealthProcessor))] + private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); + private IEnumerable hudOverlays => CreatedDrawables.OfType(); // best way to check without exposing. diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index f06236d0a8..2d6a6d95c7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; @@ -21,7 +22,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); - [Cached] + [Cached(typeof(HealthProcessor))] private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); [SetUpSteps] @@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep(@"increase hp with flash", delegate { healthProcessor.Health.Value = 0.1f; - healthProcessor.ApplyResult(new JudgementResult(null, new OsuJudgement())); + healthProcessor.ApplyResult(new JudgementResult(new HitCircle(), new OsuJudgement())); }, 3); } } From 1cb10c2a2243bde4f0fcc85a5d6de338a34f28bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 17:27:34 +0900 Subject: [PATCH 31/61] Remove unnecessary binding logic from `HUDOverlay` --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- .../TestSceneSkinEditorMultipleSkins.cs | 2 +- .../Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 6 +++--- osu.Game/Screens/Play/HUDOverlay.cs | 21 ++++--------------- osu.Game/Screens/Play/Player.cs | 2 +- 6 files changed, 11 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 861d4a4f7f..b7e92a79a0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -146,7 +146,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("create overlay", () => { - hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty()); + hudOverlay = new HUDOverlay(null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index ac5599cc27..c7c93b8892 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Gameplay var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap); - var hudOverlay = new HUDOverlay(scoreProcessor, drawableRuleset, Array.Empty()) + var hudOverlay = new HUDOverlay(drawableRuleset, Array.Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 7a960a09fc..c92e9dcfd5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay { SetContents(() => { - hudOverlay = new HUDOverlay(scoreProcessor, null, Array.Empty()); + hudOverlay = new HUDOverlay(null, Array.Empty()); // Add any key just to display the key counter visually. hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 37d10a5320..998a9fb7e7 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -22,11 +22,11 @@ namespace osu.Game.Screens.Play.HUD private readonly HitWindows hitWindows; - private readonly ScoreProcessor processor; + [Resolved] + private ScoreProcessor processor { get; set; } - public HitErrorDisplay(ScoreProcessor processor, HitWindows hitWindows) + public HitErrorDisplay(HitWindows hitWindows) { - this.processor = processor; this.hitWindows = hitWindows; RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index fd1aea016b..22812b779f 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -14,7 +14,6 @@ using osu.Game.Input.Bindings; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play.HUD; using osuTK; @@ -39,14 +38,11 @@ namespace osu.Game.Screens.Play public readonly SkinnableHealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; - public readonly HitErrorDisplay HitErrorDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; - public readonly FailingLayer FailingLayer; public Bindable ShowHealthbar = new Bindable(true); - private readonly ScoreProcessor scoreProcessor; private readonly DrawableRuleset drawableRuleset; private readonly IReadOnlyList mods; @@ -74,9 +70,8 @@ namespace osu.Game.Screens.Play private IEnumerable hideTargets => new Drawable[] { visibilityContainer, KeyCounter, topRightElements }; - public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList mods) + public HUDOverlay(DrawableRuleset drawableRuleset, IReadOnlyList mods) { - this.scoreProcessor = scoreProcessor; this.drawableRuleset = drawableRuleset; this.mods = mods; @@ -84,7 +79,7 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - FailingLayer = CreateFailingLayer(), + CreateFailingLayer(), visibilityContainer = new Container { RelativeSizeAxes = Axes.Both, @@ -104,7 +99,7 @@ namespace osu.Game.Screens.Play AccuracyCounter = CreateAccuracyCounter(), ScoreCounter = CreateScoreCounter(), CreateComboCounter(), - HitErrorDisplay = CreateHitErrorDisplayOverlay(), + CreateHitErrorDisplayOverlay(), } }, }, @@ -156,9 +151,6 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader(true)] private void load(OsuConfigManager config, NotificationOverlay notificationOverlay) { - if (scoreProcessor != null) - BindScoreProcessor(scoreProcessor); - if (drawableRuleset != null) { BindDrawableRuleset(drawableRuleset); @@ -309,15 +301,10 @@ namespace osu.Game.Screens.Play AutoSizeAxes = Axes.Both, }; - protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset?.FirstAvailableHitWindows); + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(drawableRuleset?.FirstAvailableHitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); - protected virtual void BindScoreProcessor(ScoreProcessor processor) - { - AccuracyCounter?.Current.BindTo(processor.Accuracy); - } - public bool OnPressed(GlobalAction action) { switch (action) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1538899281..116cf3cc99 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -345,7 +345,7 @@ namespace osu.Game.Screens.Play // display the cursor above some HUD elements. DrawableRuleset.Cursor?.CreateProxy() ?? new Container(), DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(), - HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value) + HUDOverlay = new HUDOverlay(DrawableRuleset, Mods.Value) { HoldToQuit = { From 111b501ced835f83a4001fc3948eb26816c08364 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 7 May 2021 18:04:38 +0900 Subject: [PATCH 32/61] Revert accidental removal of UTF-8 BOM --- osu.Game/Rulesets/Replays/AutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index 6ce857b14b..83e85146d4 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; From 9fe6e1096ab9d9264f97f52ba8ed7ae504983d0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 18:11:08 +0900 Subject: [PATCH 33/61] Remove cruft from `SkinnableHealthDisplay` --- .../Play/HUD/SkinnableHealthDisplay.cs | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs b/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs index ef0affa417..3ba6a33276 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableHealthDisplay.cs @@ -1,33 +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; -using osu.Framework.Bindables; -using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { public class SkinnableHealthDisplay : SkinnableDrawable { - public Bindable Current { get; } = new BindableDouble(1) - { - MinValue = 0, - MaxValue = 1 - }; - - private HealthProcessor processor; - - public void BindHealthProcessor(HealthProcessor processor) - { - if (this.processor != null) - throw new InvalidOperationException("Can't bind to a processor more than once"); - - this.processor = processor; - - Current.BindTo(processor.Health); - } - public SkinnableHealthDisplay() : base(new HUDSkinComponent(HUDSkinComponents.HealthDisplay), _ => new DefaultHealthDisplay()) { From a1aeac567710b95f27b07daede58b9a1ad56ab45 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 18:11:59 +0900 Subject: [PATCH 34/61] Remove remaining cruft from `SkinnableAccuracyCounter` --- osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs index 17c2493d2d..fcb8fca35d 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs @@ -1,15 +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.Framework.Bindables; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { public class SkinnableAccuracyCounter : SkinnableDrawable { - public Bindable Current { get; } = new Bindable(); - public SkinnableAccuracyCounter() : base(new HUDSkinComponent(HUDSkinComponents.AccuracyCounter), _ => new DefaultAccuracyCounter()) { From 5b2f786f971ef65100be176ebc828b87e87f8c3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 19:16:00 +0900 Subject: [PATCH 35/61] 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 99cda7693d..80b1c5b52f 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e448972066..29189781a7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -29,7 +29,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 43ed2d7dc8..c4eb7aefba 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From 8c564a69ed1978e2e11be2d93806c57a759c5800 Mon Sep 17 00:00:00 2001 From: Christine Chen Date: Fri, 7 May 2021 20:59:20 -0400 Subject: [PATCH 36/61] Fix InvalidOperationException when exiting a map at the end --- .../Visual/Gameplay/TestSceneStoryboardWithOutro.cs | 10 ++++++++++ osu.Game/Screens/Play/Player.cs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs index 4138a81ebd..e1dc6e3b42 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs @@ -133,6 +133,16 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= currentStoryboardDuration); } + [Test] + public void TestPerformExitNoOutro() + { + CreateTest(null); + AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false)); + AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); + AddStep("exit via pause", () => Player.ExitViaPause()); + AddAssert("score shown", () => Player.IsScoreShown); + } + protected override bool AllowFail => true; protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 88e617245b..0a2f9f0d18 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -542,7 +542,11 @@ namespace osu.Game.Screens.Play // if the score is ready for display but results screen has not been pushed yet (e.g. storyboard is still playing beyond gameplay), then transition to results screen instead of exiting. if (prepareScoreForDisplayTask != null) + { + completionProgressDelegate?.Cancel(); + completionProgressDelegate = null; updateCompletionState(true); + } } this.Exit(); From df630d94282250064ba396d06b518b3ab369447d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 14:53:19 +0200 Subject: [PATCH 37/61] Trim redundant `this` qualifier --- .../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 32d2fba25e..d57acd005b 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; From 63e267a3beefbb0c7344521af93d1a340a5a454c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 May 2021 23:32:52 +0900 Subject: [PATCH 38/61] Revert "Trim redundant `this` qualifier" This reverts commit df630d94282250064ba396d06b518b3ab369447d. --- .../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 d57acd005b..32d2fba25e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; From 01d732bb65202f66737d478457d62f1af1cd1884 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 May 2021 23:33:03 +0900 Subject: [PATCH 39/61] Revert "Refactor `SliderSelectionBlueprint` to not reference blueprint pieces for input handling" This reverts commit 54fe10c82a855a16c88f8781a9ae12dc42df7b0e. --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 6 ++++++ .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 ++-- 2 files changed, 8 insertions(+), 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 ece9c7a757..6e22c35ab3 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,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; + + // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. + // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. + AlwaysPresent = true; } [BackgroundDependencyLoader] @@ -50,5 +54,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } public void RecyclePath() => body.RecyclePath(); + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 32d2fba25e..88fcb1e715 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,10 +240,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; + BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); } From fe86ee629ed8b7a7a36eb7048064192cf9584672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 16:30:08 +0200 Subject: [PATCH 40/61] Fix temp files from beatmap listing imports not being cleaned up As reported in #12718, it turns out that temporary files from beatmap set downloads performed via the beatmap listing overlay could remain in the user's filesystem even after the download has concluded. The reason for the issue is a failure in component integration. In the case of online downloads, files are first downloaded to a temporary directory (`C:/Temp` or `/tmp`), with a randomly generated filename, which ends in an extension of `.tmp`. On the other side, `ArchiveModelManager`s have a `ShouldDeleteArchive()` method, which determines whether a file should be deleted after importing. At the time of writing, in the case of beatmap imports the file is only automatically cleaned up if the extension of the file is equal to `.osz`, which was not the case for temporary files. As it turns out, `APIDownloadRequest` has a facility for adjusting the file's extension, via the protected `FileExtension` property. Therefore, use it in the case of `DownloadBeatmapSetRequest` to specify `.osz`, which then will make sure that the `ShouldDeleteArchive()` check in `BeatmapManager` picks it up for clean-up. --- osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index e8871bef05..2898955de7 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -23,6 +23,8 @@ namespace osu.Game.Online.API.Requests return req; } + protected override string FileExtension => ".osz"; + protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; } } From 25312b3e88d47b2cbc9ce327d2c6d05954b39d72 Mon Sep 17 00:00:00 2001 From: Christine Chen Date: Sat, 8 May 2021 11:45:31 -0400 Subject: [PATCH 41/61] Don't restart completion delegate on exit, revert exit behavior to lazer --- .../Visual/Gameplay/TestSceneStoryboardWithOutro.cs | 2 +- osu.Game/Screens/Play/Player.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs index e1dc6e3b42..70b1d3ef85 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs @@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); AddStep("exit via pause", () => Player.ExitViaPause()); - AddAssert("score shown", () => Player.IsScoreShown); + AddAssert("score not shown", () => !Player.IsScoreShown); } protected override bool AllowFail => true; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0a2f9f0d18..557dd2a78a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -541,10 +541,8 @@ namespace osu.Game.Screens.Play } // if the score is ready for display but results screen has not been pushed yet (e.g. storyboard is still playing beyond gameplay), then transition to results screen instead of exiting. - if (prepareScoreForDisplayTask != null) + if (prepareScoreForDisplayTask != null && completionProgressDelegate == null) { - completionProgressDelegate?.Cancel(); - completionProgressDelegate = null; updateCompletionState(true); } } From c3bf6a0287c16682e71a750728c40cfc2a99b06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 21:01:37 +0200 Subject: [PATCH 42/61] Remove weird vestigial `Current` reimplementation Has no functional purpose anymore since the changes in the HUD element data binding flow. --- osu.Game/Skinning/LegacyScoreCounter.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index 21112aa107..ecb907e601 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.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.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Screens.Play.HUD; @@ -16,8 +15,6 @@ namespace osu.Game.Skinning protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; - public new Bindable Current { get; } = new Bindable(); - public LegacyScoreCounter(ISkin skin) : base(6) { @@ -26,9 +23,6 @@ namespace osu.Game.Skinning this.skin = skin; - // base class uses int for display, but externally we bind to ScoreProcessor as a double for now. - Current.BindValueChanged(v => base.Current.Value = (int)v.NewValue); - Scale = new Vector2(0.96f); Margin = new MarginPadding(10); } From efb9164658a127093cf39672466bafbb89268e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 21:35:12 +0200 Subject: [PATCH 43/61] Restore previous test scene logic --- .../Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs index 34356184a2..6a8a2187f9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs @@ -1,8 +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 NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Testing; @@ -15,8 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneSkinnableAccuracyCounter : SkinnableTestScene { - private IEnumerable accuracyCounters => CreatedDrawables.OfType(); - protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); [Cached] @@ -25,7 +21,8 @@ namespace osu.Game.Tests.Visual.Gameplay [SetUpSteps] public void SetUpSteps() { - AddStep("Create combo counters", () => SetContents(() => new SkinnableAccuracyCounter())); + AddStep("Set initial accuracy", () => scoreProcessor.Accuracy.Value = 1); + AddStep("Create accuracy counters", () => SetContents(() => new SkinnableAccuracyCounter())); } [Test] @@ -33,7 +30,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep(@"Reset all", () => scoreProcessor.Accuracy.Value = 1); - AddStep(@"Hit! :D", () => scoreProcessor.Accuracy.Value -= 0.23); + AddStep(@"Miss :(", () => scoreProcessor.Accuracy.Value -= 0.023); } } } From 67cea6e762f8dd2ff0e886bc2fc1ea6c79c56ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 21:38:03 +0200 Subject: [PATCH 44/61] Remove explicit binding to accuracy counter from overlay --- osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs | 3 --- osu.Game/Screens/Play/HUDOverlay.cs | 2 -- 2 files changed, 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs index 17c2493d2d..fcb8fca35d 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableAccuracyCounter.cs @@ -1,15 +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.Framework.Bindables; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { public class SkinnableAccuracyCounter : SkinnableDrawable { - public Bindable Current { get; } = new Bindable(); - public SkinnableAccuracyCounter() : base(new HUDSkinComponent(HUDSkinComponents.AccuracyCounter), _ => new DefaultAccuracyCounter()) { diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index c887fb78e0..e9b376c433 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -320,8 +320,6 @@ namespace osu.Game.Screens.Play protected virtual void BindScoreProcessor(ScoreProcessor processor) { - AccuracyCounter?.Current.BindTo(processor.Accuracy); - if (HealthDisplay is IHealthDisplay shd) { processor.NewJudgement += judgement => From 342c5a5938253c961bfc97d2e1239f74ba20f4d9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 04:49:40 +0300 Subject: [PATCH 45/61] Add tests to indicate the issue --- .../Visual/Online/TestSceneNewsOverlay.cs | 62 ++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 6ebe8fcc07..f10b385c61 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -2,7 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -14,21 +17,34 @@ namespace osu.Game.Tests.Visual.Online { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private NewsOverlay news; + private NewsOverlay overlay; [SetUp] - public void SetUp() => Schedule(() => Child = news = new NewsOverlay()); + public void SetUp() => Schedule(() => Child = overlay = new NewsOverlay()); [Test] public void TestRequest() { setUpNewsResponse(responseExample); - AddStep("Show", () => news.Show()); - AddStep("Show article", () => news.ShowArticle("article")); + AddStep("Show", () => overlay.Show()); + AddStep("Show article", () => overlay.ShowArticle("article")); } - private void setUpNewsResponse(GetNewsResponse r) - => AddStep("set up response", () => + [Test] + public void TestCursorRequest() + { + setUpNewsResponse(responseWithCursor, "Set up cursor response"); + AddStep("Show", () => overlay.Show()); + AddAssert("Show More button is visible", () => showMoreButton.Alpha == 1); + setUpNewsResponse(responseWithNoCursor, "Set up no cursor response"); + AddStep("Click Show More", () => showMoreButton.Click()); + AddAssert("Show More button is hidden", () => showMoreButton.Alpha == 0); + } + + private ShowMoreButton showMoreButton => overlay.ChildrenOfType().First(); + + private void setUpNewsResponse(GetNewsResponse r, string testName = "Set up response") + => AddStep(testName, () => { dummyAPI.HandleRequest = request => { @@ -40,7 +56,7 @@ namespace osu.Game.Tests.Visual.Online }; }); - private GetNewsResponse responseExample => new GetNewsResponse + private static GetNewsResponse responseExample => new GetNewsResponse { NewsPosts = new[] { @@ -62,5 +78,37 @@ namespace osu.Game.Tests.Visual.Online } } }; + + private static GetNewsResponse responseWithCursor => new GetNewsResponse + { + NewsPosts = new[] + { + new APINewsPost + { + Title = "This post has an image which starts with \"/\" and has many authors!", + Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + Author = "someone, someone1, someone2, someone3, someone4", + FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png", + PublishedAt = DateTimeOffset.Now + } + }, + Cursor = new Cursor() + }; + + private static GetNewsResponse responseWithNoCursor => new GetNewsResponse + { + NewsPosts = new[] + { + new APINewsPost + { + Title = "This post has a full-url image! (HTML entity: &)", + Preview = "boom (HTML entity: &)", + Author = "user (HTML entity: &)", + FirstImage = "https://assets.ppy.sh/artists/88/header.jpg", + PublishedAt = DateTimeOffset.Now + } + }, + Cursor = null + }; } } From dde9fd28e6872e2afe41670861ffb7ec510b74b9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 04:57:24 +0300 Subject: [PATCH 46/61] Hide ShowMore button if there's nothing to load --- osu.Game/Overlays/News/Displays/FrontPageDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs index 0f177f151a..a1bc6c650b 100644 --- a/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs +++ b/osu.Game/Overlays/News/Displays/FrontPageDisplay.cs @@ -100,7 +100,7 @@ namespace osu.Game.Overlays.News.Displays { content.Add(loaded); showMore.IsLoading = false; - showMore.Show(); + showMore.Alpha = lastCursor == null ? 0 : 1; }, (cancellationToken = new CancellationTokenSource()).Token); } From ae2b5a0806c3b0cad6dba614f1273d9d121cf0f6 Mon Sep 17 00:00:00 2001 From: Christine Chen Date: Sat, 8 May 2021 22:42:14 -0400 Subject: [PATCH 47/61] Actually test that player was exited --- osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs index 70b1d3ef85..0ac8e01482 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs @@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false)); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); AddStep("exit via pause", () => Player.ExitViaPause()); - AddAssert("score not shown", () => !Player.IsScoreShown); + AddAssert("player exited", () => Stack.CurrentScreen == null); } protected override bool AllowFail => true; From 0818deac17110c65ae22005c5616c55e67913847 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 06:06:34 +0300 Subject: [PATCH 48/61] Fix potential test scene failure due to showMoreButton not being loaded in time --- osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index f10b385c61..46454879da 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -35,6 +35,7 @@ namespace osu.Game.Tests.Visual.Online { setUpNewsResponse(responseWithCursor, "Set up cursor response"); AddStep("Show", () => overlay.Show()); + AddUntilStep("Show more button is ready", () => showMoreButton != null); AddAssert("Show More button is visible", () => showMoreButton.Alpha == 1); setUpNewsResponse(responseWithNoCursor, "Set up no cursor response"); AddStep("Click Show More", () => showMoreButton.Click()); From 8868439ce46b042b2eae1bd7fc48614ac30d9197 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 06:49:12 +0300 Subject: [PATCH 49/61] Another approach to fix test scene failure --- osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 46454879da..0be09d1fcc 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -36,10 +36,10 @@ namespace osu.Game.Tests.Visual.Online setUpNewsResponse(responseWithCursor, "Set up cursor response"); AddStep("Show", () => overlay.Show()); AddUntilStep("Show more button is ready", () => showMoreButton != null); - AddAssert("Show More button is visible", () => showMoreButton.Alpha == 1); + AddAssert("Show More button is visible", () => showMoreButton?.Alpha == 1); setUpNewsResponse(responseWithNoCursor, "Set up no cursor response"); - AddStep("Click Show More", () => showMoreButton.Click()); - AddAssert("Show More button is hidden", () => showMoreButton.Alpha == 0); + AddStep("Click Show More", () => showMoreButton?.Click()); + AddAssert("Show More button is hidden", () => showMoreButton?.Alpha == 0); } private ShowMoreButton showMoreButton => overlay.ChildrenOfType().First(); From f0c1784d05a56dea2082473ca02063c1721bdad1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 09:12:37 +0300 Subject: [PATCH 50/61] Use FirstOrDefault instead of First --- osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 0be09d1fcc..ba692a7769 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Show More button is hidden", () => showMoreButton?.Alpha == 0); } - private ShowMoreButton showMoreButton => overlay.ChildrenOfType().First(); + private ShowMoreButton showMoreButton => overlay.ChildrenOfType().FirstOrDefault(); private void setUpNewsResponse(GetNewsResponse r, string testName = "Set up response") => AddStep(testName, () => From 879c08e6667024694dde3b8bb095b00185a3f3c3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 9 May 2021 10:06:36 +0300 Subject: [PATCH 51/61] Use UntilStep instead of Assert to check button visibility --- osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index ba692a7769..93a5b6fc59 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -35,11 +35,10 @@ namespace osu.Game.Tests.Visual.Online { setUpNewsResponse(responseWithCursor, "Set up cursor response"); AddStep("Show", () => overlay.Show()); - AddUntilStep("Show more button is ready", () => showMoreButton != null); - AddAssert("Show More button is visible", () => showMoreButton?.Alpha == 1); + AddUntilStep("Show More button is visible", () => showMoreButton?.Alpha == 1); setUpNewsResponse(responseWithNoCursor, "Set up no cursor response"); AddStep("Click Show More", () => showMoreButton?.Click()); - AddAssert("Show More button is hidden", () => showMoreButton?.Alpha == 0); + AddUntilStep("Show More button is hidden", () => showMoreButton?.Alpha == 0); } private ShowMoreButton showMoreButton => overlay.ChildrenOfType().FirstOrDefault(); From 8964d51de984f3089f5016d184e58b5ba222654e Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 9 May 2021 14:10:38 -0700 Subject: [PATCH 52/61] Add ability to sort by source in song select --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 1 + osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 3 +++ osu.Game/Screens/Select/Filter/SortMode.cs | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 5731b1ac2c..643f4131dc 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -304,6 +304,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep(@"Sort by BPM", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.BPM)); AddStep(@"Sort by Length", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Length)); AddStep(@"Sort by Difficulty", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Difficulty)); + AddStep(@"Sort by Source", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Source)); } [Test] diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index bf045ed612..635f1d8e1e 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -82,6 +82,9 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.Difficulty: return compareUsingAggregateMax(otherSet, b => b.StarDifficulty); + + case SortMode.Source: + return string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase); } } diff --git a/osu.Game/Screens/Select/Filter/SortMode.cs b/osu.Game/Screens/Select/Filter/SortMode.cs index be76fbc3ba..db0e6812b8 100644 --- a/osu.Game/Screens/Select/Filter/SortMode.cs +++ b/osu.Game/Screens/Select/Filter/SortMode.cs @@ -29,6 +29,9 @@ namespace osu.Game.Screens.Select.Filter RankAchieved, [Description("Title")] - Title + Title, + + [Description("Source")] + Source, } } From a21718f1cd89139f684835de8d2dd7d432da2de6 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 9 May 2021 14:26:45 -0700 Subject: [PATCH 53/61] Move source case to a better spot --- osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 635f1d8e1e..00c2c2cb4a 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -71,6 +71,9 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.Author: return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase); + case SortMode.Source: + return string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase); + case SortMode.DateAdded: return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); @@ -82,9 +85,6 @@ namespace osu.Game.Screens.Select.Carousel case SortMode.Difficulty: return compareUsingAggregateMax(otherSet, b => b.StarDifficulty); - - case SortMode.Source: - return string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase); } } From a71e52da4caf53c88b772263d4b7fb89090a34ec Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 9 May 2021 15:39:59 -0700 Subject: [PATCH 54/61] Fix enum ordering after adding source --- osu.Game/Screens/Select/Filter/SortMode.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Filter/SortMode.cs b/osu.Game/Screens/Select/Filter/SortMode.cs index db0e6812b8..18c5d713e1 100644 --- a/osu.Game/Screens/Select/Filter/SortMode.cs +++ b/osu.Game/Screens/Select/Filter/SortMode.cs @@ -28,10 +28,10 @@ namespace osu.Game.Screens.Select.Filter [Description("Rank Achieved")] RankAchieved, - [Description("Title")] - Title, - [Description("Source")] Source, + + [Description("Title")] + Title, } } From ab6239fd5f4545077162a2adec8352c789426cf0 Mon Sep 17 00:00:00 2001 From: Susko3 <16479013+Susko3@users.noreply.github.com> Date: Mon, 10 May 2021 00:51:58 +0200 Subject: [PATCH 55/61] change math for displaying volume "MAX" --- osu.Game/Overlays/Volume/VolumeMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index f1f21bec49..a15076581e 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -204,7 +204,7 @@ namespace osu.Game.Overlays.Volume { displayVolume = value; - if (displayVolume > 0.99f) + if (displayVolume >= 0.995f) { text.Text = "MAX"; maxGlow.EffectColour = meterColour.Opacity(2f); From 132bb7832d31e2c30719c65dd4da18d8fbbc2691 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 May 2021 12:06:33 +0900 Subject: [PATCH 56/61] Fix some regressions when updating test scenes --- .../Visual/Gameplay/TestSceneFailingLayer.cs | 7 ++----- .../Gameplay/TestSceneSkinnableHealthDisplay.cs | 11 +++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs index 99facb2731..ebc431a78b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Configuration; @@ -21,17 +22,13 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private OsuConfigManager config { get; set; } - [SetUpSteps] - public void SetUpSteps() - { - } - private void create(HealthProcessor healthProcessor) { AddStep("create layer", () => { Child = new HealthProcessorContainer(healthProcessor) { + RelativeSizeAxes = Axes.Both, Child = layer = new FailingLayer() }; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index 2d6a6d95c7..4f50613416 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -43,18 +43,21 @@ namespace osu.Game.Tests.Visual.Gameplay { AddRepeatStep(@"decrease hp", delegate { - healthProcessor.Health.Value = 0.08f; + healthProcessor.Health.Value -= 0.08f; }, 10); AddRepeatStep(@"increase hp without flash", delegate { - healthProcessor.Health.Value = 0.1f; + healthProcessor.Health.Value += 0.1f; }, 3); AddRepeatStep(@"increase hp with flash", delegate { - healthProcessor.Health.Value = 0.1f; - healthProcessor.ApplyResult(new JudgementResult(new HitCircle(), new OsuJudgement())); + healthProcessor.Health.Value += 0.1f; + healthProcessor.ApplyResult(new JudgementResult(new HitCircle(), new OsuJudgement()) + { + Type = HitResult.Perfect + }); }, 3); } } From 1bbbe8042099a5b1c3b659b1b899e2970651425c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 May 2021 12:20:22 +0900 Subject: [PATCH 57/61] Fix missing instances of `HealthProcessor` caching --- .../Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs | 1 + osu.Game/Screens/Play/Player.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 7c65601d50..ac5599cc27 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -18,6 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene { + [Cached] private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(); [Cached(typeof(HealthProcessor))] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 396a9f841d..ba34ed4750 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -208,6 +208,8 @@ namespace osu.Game.Screens.Play HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor.ApplyBeatmap(playableBeatmap); + dependencies.CacheAs(HealthProcessor); + if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); From 1d38fa29b5a853a2be449ff00e3732359b0fbe00 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 May 2021 12:23:04 +0900 Subject: [PATCH 58/61] Remove unused using statement --- osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs index ebc431a78b..fb4c9d713a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs @@ -6,7 +6,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; From 35a7226cd82120207014a652567a5e87febc25e2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 May 2021 13:41:04 +0900 Subject: [PATCH 59/61] Add newline --- osu.Game/Screens/Play/HUD/HealthDisplay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HealthDisplay.cs b/osu.Game/Screens/Play/HUD/HealthDisplay.cs index 2292f64989..6c2571cc28 100644 --- a/osu.Game/Screens/Play/HUD/HealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HealthDisplay.cs @@ -39,7 +39,8 @@ namespace osu.Game.Screens.Play.HUD private void onNewJudgement(JudgementResult judgement) { - if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit) Flash(judgement); + if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit) + Flash(judgement); } protected override void Dispose(bool isDisposing) From 97e72849af46241de4acbe4e955c5e6a72db9434 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 May 2021 15:19:27 +0900 Subject: [PATCH 60/61] Fix regressed `HitErrorDisplay` behaviour (and localise binding to meter implementations) --- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 39 +++++++------------ osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 24 ------------ .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 +- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 2 +- .../Play/HUD/HitErrorMeters/HitErrorMeter.cs | 29 +++++++++++++- 5 files changed, 45 insertions(+), 51 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 1021ac3760..6cefd01aab 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -2,15 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Game.Rulesets.Judgements; -using osu.Framework.Utils; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Catch.Scoring; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Scoring; -using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Scoring; @@ -20,14 +21,11 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneHitErrorMeter : OsuTestScene { - private BarHitErrorMeter barMeter; - private BarHitErrorMeter barMeter2; - private BarHitErrorMeter barMeter3; - private ColourHitErrorMeter colourMeter; - private ColourHitErrorMeter colourMeter2; - private ColourHitErrorMeter colourMeter3; private HitWindows hitWindows; + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + public TestSceneHitErrorMeter() { recreateDisplay(new OsuHitWindows(), 5); @@ -105,40 +103,40 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(barMeter = new BarHitErrorMeter(hitWindows, true) + Add(new BarHitErrorMeter(hitWindows, true) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, }); - Add(barMeter2 = new BarHitErrorMeter(hitWindows, false) + Add(new BarHitErrorMeter(hitWindows, false) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }); - Add(barMeter3 = new BarHitErrorMeter(hitWindows, true) + Add(new BarHitErrorMeter(hitWindows, true) { Anchor = Anchor.BottomCentre, Origin = Anchor.CentreLeft, Rotation = 270, }); - Add(colourMeter = new ColourHitErrorMeter(hitWindows) + Add(new ColourHitErrorMeter(hitWindows) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Margin = new MarginPadding { Right = 50 } }); - Add(colourMeter2 = new ColourHitErrorMeter(hitWindows) + Add(new ColourHitErrorMeter(hitWindows) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Margin = new MarginPadding { Left = 50 } }); - Add(colourMeter3 = new ColourHitErrorMeter(hitWindows) + Add(new ColourHitErrorMeter(hitWindows) { Anchor = Anchor.BottomCentre, Origin = Anchor.CentreLeft, @@ -149,18 +147,11 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(double offset = 0) { - var judgement = new JudgementResult(new HitObject(), new Judgement()) + scoreProcessor.ApplyResult(new JudgementResult(new HitCircle { HitWindows = hitWindows }, new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, - }; - - barMeter.OnNewJudgement(judgement); - barMeter2.OnNewJudgement(judgement); - barMeter3.OnNewJudgement(judgement); - colourMeter.OnNewJudgement(judgement); - colourMeter2.OnNewJudgement(judgement); - colourMeter3.OnNewJudgement(judgement); + }); } } } diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 998a9fb7e7..a24d9c10cb 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -7,7 +7,6 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD.HitErrorMeters; @@ -22,17 +21,11 @@ namespace osu.Game.Screens.Play.HUD private readonly HitWindows hitWindows; - [Resolved] - private ScoreProcessor processor { get; set; } - public HitErrorDisplay(HitWindows hitWindows) { this.hitWindows = hitWindows; RelativeSizeAxes = Axes.Both; - - if (processor != null) - processor.NewJudgement += onNewJudgement; } [BackgroundDependencyLoader] @@ -47,15 +40,6 @@ namespace osu.Game.Screens.Play.HUD type.BindValueChanged(typeChanged, true); } - private void onNewJudgement(JudgementResult result) - { - if (result.HitObject.HitWindows.WindowFor(HitResult.Miss) == 0) - return; - - foreach (var c in Children) - c.OnNewJudgement(result); - } - private void typeChanged(ValueChangedEvent type) { Children.ForEach(c => c.FadeOut(fade_duration, Easing.OutQuint)); @@ -139,13 +123,5 @@ namespace osu.Game.Screens.Play.HUD Add(display); display.FadeInFromZero(fade_duration, Easing.OutQuint); } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (processor != null) - processor.NewJudgement -= onNewJudgement; - } } } diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 3b24c8cc9e..c5a21ade03 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -214,7 +214,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private const int max_concurrent_judgements = 50; - public override void OnNewJudgement(JudgementResult judgement) + protected override void OnNewJudgement(JudgementResult judgement) { if (!judgement.IsHit) return; diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 657235bfd4..465439cf19 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters InternalChild = judgementsFlow = new JudgementFlow(); } - public override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset))); + protected override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset))); private class JudgementFlow : FillFlowContainer { diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index b3edfdedec..8b53a9676d 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -14,6 +14,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { protected readonly HitWindows HitWindows; + [Resolved] + private ScoreProcessor processor { get; set; } + [Resolved] private OsuColour colours { get; set; } @@ -22,7 +25,23 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters HitWindows = hitWindows; } - public abstract void OnNewJudgement(JudgementResult judgement); + protected override void LoadComplete() + { + base.LoadComplete(); + + if (processor != null) + processor.NewJudgement += onNewJudgement; + } + + private void onNewJudgement(JudgementResult result) + { + if (result.HitObject.HitWindows?.WindowFor(HitResult.Miss) == 0) + return; + + OnNewJudgement(result); + } + + protected abstract void OnNewJudgement(JudgementResult judgement); protected Color4 GetColourForHitResult(HitResult result) { @@ -47,5 +66,13 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters return colours.BlueLight; } } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (processor != null) + processor.NewJudgement -= onNewJudgement; + } } } From fa872858b592278b7672c16fbd840825d8ac7a24 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 May 2021 16:40:06 +0900 Subject: [PATCH 61/61] Remove unnecessary check --- osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index 8b53a9676d..37e9ea43c5 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -29,8 +29,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { base.LoadComplete(); - if (processor != null) - processor.NewJudgement += onNewJudgement; + processor.NewJudgement += onNewJudgement; } private void onNewJudgement(JudgementResult result)