From 214154c5124a67670337cfed99b688420b81ac38 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 21 Dec 2017 20:23:10 +0100 Subject: [PATCH 01/31] hide unnecessary lines on empty BeatmapInfoWedge adding back deleted line ooops meh --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 34 +++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3ef6ceeaeb..d18aebe43b 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select List labels = new List(); - if (beatmap != null) + if (beatmap != null && !(working is DummyWorkingBeatmap)) { HitObject lastObject = beatmap.HitObjects.LastOrDefault(); double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; @@ -200,21 +200,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = new[] - { - new OsuSpriteText - { - Font = @"Exo2.0-Medium", - Text = "mapped by ", - TextSize = 15, - }, - new OsuSpriteText - { - Font = @"Exo2.0-Bold", - Text = metadata.Author.Username, - TextSize = 15, - }, - } + Children = working is DummyWorkingBeatmap ? Array.Empty() : getMapper(metadata) }, new FillFlowContainer { @@ -228,6 +214,22 @@ namespace osu.Game.Screens.Select }; } + private OsuSpriteText[] getMapper(BeatmapMetadata metadata) => new[] + { + new OsuSpriteText + { + Font = @"Exo2.0-Medium", + Text = "mapped by ", + TextSize = 15, + }, + new OsuSpriteText + { + Font = @"Exo2.0-Bold", + Text = metadata.Author.Username, + TextSize = 15, + } + }; + private string getBPMRange(Beatmap beatmap) { double bpmMax = beatmap.ControlPointInfo.BPMMaximum; From 07f55a2a606a7d8a12973b637aa7e875c692b105 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 10:18:25 +0100 Subject: [PATCH 02/31] remove references to DummyWorkingBeatmap determine content by data that is present instead --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 106 +++++++++++--------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index d18aebe43b..9b9a009ac0 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -89,34 +89,8 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load() { - BeatmapInfo beatmapInfo = working.BeatmapInfo; - BeatmapMetadata metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - Beatmap beatmap = working.Beatmap; - - List labels = new List(); - - if (beatmap != null && !(working is DummyWorkingBeatmap)) - { - HitObject lastObject = beatmap.HitObjects.LastOrDefault(); - double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "Length", - Icon = FontAwesome.fa_clock_o, - Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), - })); - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "BPM", - Icon = FontAwesome.fa_circle, - Content = getBPMRange(beatmap), - })); - - //get statistics from the current ruleset. - labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s))); - } + var beatmapInfo = working.BeatmapInfo; + var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); PixelSnapping = true; CacheDrawnFrameBuffer = true; @@ -186,7 +160,7 @@ namespace osu.Game.Screens.Select new OsuSpriteText { Font = @"Exo2.0-MediumItalic", - Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title, + Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title, TextSize = 28, }, new OsuSpriteText @@ -200,46 +174,86 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = working is DummyWorkingBeatmap ? Array.Empty() : getMapper(metadata) + Children = getMapper(metadata) }, new FillFlowContainer { Margin = new MarginPadding { Top = 20 }, Spacing = new Vector2(20, 0), AutoSizeAxes = Axes.Both, - Children = labels - }, + Children = getInfoLabels() + } } - }, + } }; } - private OsuSpriteText[] getMapper(BeatmapMetadata metadata) => new[] + private InfoLabel[] getInfoLabels() { - new OsuSpriteText + var beatmap = working.Beatmap; + var info = working.BeatmapInfo; + + List labels = new List(); + + if (beatmap?.HitObjects?.Count > 0) { - Font = @"Exo2.0-Medium", - Text = "mapped by ", - TextSize = 15, - }, - new OsuSpriteText - { - Font = @"Exo2.0-Bold", - Text = metadata.Author.Username, - TextSize = 15, + HitObject lastObject = beatmap.HitObjects.LastOrDefault(); + double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "Length", + Icon = FontAwesome.fa_clock_o, + Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + })); + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "BPM", + Icon = FontAwesome.fa_circle, + Content = getBPMRange(beatmap), + })); + + //get statistics from the current ruleset. + labels.AddRange(info.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s))); } - }; + + return labels.ToArray(); + } private string getBPMRange(Beatmap beatmap) { double bpmMax = beatmap.ControlPointInfo.BPMMaximum; double bpmMin = beatmap.ControlPointInfo.BPMMinimum; - if (Precision.AlmostEquals(bpmMin, bpmMax)) return $"{bpmMin:0}"; + if (Precision.AlmostEquals(bpmMin, bpmMax)) + return $"{bpmMin:0}"; return $"{bpmMin:0}-{bpmMax:0} (mostly {beatmap.ControlPointInfo.BPMMode:0})"; } + private OsuSpriteText[] getMapper(BeatmapMetadata metadata) + { + if (string.IsNullOrEmpty(metadata.Author?.Username)) + return Array.Empty(); + + return new[] + { + new OsuSpriteText + { + Font = @"Exo2.0-Medium", + Text = "mapped by ", + TextSize = 15, + }, + new OsuSpriteText + { + Font = @"Exo2.0-Bold", + Text = metadata.Author.Username, + TextSize = 15, + } + }; + } + public class InfoLabel : Container, IHasTooltip { public string TooltipText { get; private set; } From ed827d5424fcadfa24e76a13cfbe1100916cfb00 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 12:33:52 +0100 Subject: [PATCH 03/31] more visual tests for BeatmapInfoWedge also fix Author showing when not wanted --- .../Visual/TestCaseBeatmapInfoWedge.cs | 117 ++++++++++++++---- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 25 ++-- 3 files changed, 109 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 0168cedc86..353f351a54 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -1,36 +1,48 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; +using System.Collections.Generic; +using System.Linq; using OpenTK; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu; using osu.Game.Screens.Select; +using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { public class TestCaseBeatmapInfoWedge : OsuTestCase { - private BeatmapManager beatmaps; - private readonly Random random; - private readonly BeatmapInfoWedge infoWedge; + private TestBeatmapInfoWedge infoWedge; + private readonly List beatmaps = new List(); private readonly Bindable beatmap = new Bindable(); - public TestCaseBeatmapInfoWedge() + [BackgroundDependencyLoader] + private void load(OsuGameBase game, RulesetStore rulesets) { - random = new Random(0123); + beatmap.BindTo(game.Beatmap); - Add(infoWedge = new BeatmapInfoWedge + Add(infoWedge = new TestBeatmapInfoWedge { Size = new Vector2(0.5f, 245), RelativeSizeAxes = Axes.X, Margin = new MarginPadding { Top = 20, - }, + } + }); + + AddStep("hide", () => + { + infoWedge.State = Visibility.Hidden; + Content.FadeOut(100); }); AddStep("show", () => @@ -39,31 +51,88 @@ namespace osu.Game.Tests.Visual infoWedge.State = Visibility.Visible; infoWedge.UpdateBeatmap(beatmap); }); - AddStep("hide", () => + + foreach (var rulesetInfo in rulesets.AvailableRulesets) { - infoWedge.State = Visibility.Hidden; - Content.FadeOut(100); + var ruleset = rulesetInfo.CreateInstance(); + beatmaps.Add(createTestBeatmap(rulesetInfo)); + + var name = rulesetInfo.ShortName; + selectBeatmap(name); + + // TODO: check InfoLabels of other rulesets + switch (ruleset) + { + case OsuRuleset osu: + testOsuBeatmap(osu); + break; + } + } + + testNullBeatmap(); + } + + private void testOsuBeatmap(OsuRuleset ruleset) + { + AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version"); + AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); + AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist"); + AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Text == $"{ruleset.ShortName}Author")); + // TODO: check InfoLabels + } + + private void testNullBeatmap() + { + selectNullBeatmap(); + AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text)); + AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title); + AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist); + AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); + AddAssert("check empty infos", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); + } + + private void selectBeatmap(string name) + { + AddStep($"select {name} beatmap", () => + { + beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name)); + infoWedge.UpdateBeatmap(beatmap); }); - AddStep("random beatmap", randomBeatmap); - AddStep("null beatmap", () => infoWedge.UpdateBeatmap(beatmap.Default)); } - [BackgroundDependencyLoader] - private void load(OsuGameBase game, BeatmapManager beatmaps) + private void selectNullBeatmap() { - this.beatmaps = beatmaps; - beatmap.BindTo(game.Beatmap); + AddStep("select null beatmap", () => + { + beatmap.Value = beatmap.Default; + infoWedge.UpdateBeatmap(beatmap); + }); } - private void randomBeatmap() + private Beatmap createTestBeatmap(RulesetInfo ruleset) { - var sets = beatmaps.GetAllUsableBeatmapSets(); - if (sets.Count == 0) - return; + return new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + AuthorString = $"{ruleset.ShortName}Author", + Artist = $"{ruleset.ShortName}Artist", + Source = $"{ruleset.ShortName}Source", + Title = $"{ruleset.ShortName}Title" + }, + Ruleset = ruleset, + StarDifficulty = 6, + Version = $"{ruleset.ShortName}Version" + }, + HitObjects = new List() // TODO: Fill it with something depending on ruleset? + }; + } - var b = sets[random.Next(0, sets.Count)].Beatmaps[0]; - beatmap.Value = beatmaps.GetWorkingBeatmap(b); - infoWedge.UpdateBeatmap(beatmap); + private class TestBeatmapInfoWedge : BeatmapInfoWedge + { + public new BufferedWedgeInfo Info => base.Info; } } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 1434943da0..3ec83ed8d5 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -21,8 +21,7 @@ namespace osu.Game.Beatmaps Metadata = new BeatmapMetadata { Artist = "please load a beatmap!", - Title = "no beatmaps available!", - AuthorString = "no one", + Title = "no beatmaps available!" }, BeatmapSet = new BeatmapSetInfo(), BaseDifficulty = new BeatmapDifficulty diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 9b9a009ac0..5d4f950a51 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Select { private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0); - private Drawable info; + protected BufferedWedgeInfo Info; public BeatmapInfoWedge() { @@ -63,23 +63,28 @@ namespace osu.Game.Screens.Select LoadComponentAsync(new BufferedWedgeInfo(beatmap) { Shear = -Shear, - Depth = info?.Depth + 1 ?? 0, + Depth = Info?.Depth + 1 ?? 0, }, newInfo => { // ensure we ourselves are visible if not already. if (!IsPresent) this.FadeIn(250); - info?.FadeOut(250); - info?.Expire(); + Info?.FadeOut(250); + Info?.Expire(); - Add(info = newInfo); + Add(Info = newInfo); }); } public class BufferedWedgeInfo : BufferedContainer { private readonly WorkingBeatmap working; + public OsuSpriteText VersionLabel { get; private set; } + public OsuSpriteText TitleLabel { get; private set; } + public OsuSpriteText ArtistLabel { get; private set; } + public FillFlowContainer MapperContainer { get; private set; } + public FillFlowContainer InfoLabelContainer { get; private set; } public BufferedWedgeInfo(WorkingBeatmap working) { @@ -139,7 +144,7 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + VersionLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = beatmapInfo.Version, @@ -157,26 +162,26 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + TitleLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title, TextSize = 28, }, - new OsuSpriteText + ArtistLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = metadata.Artist, TextSize = 17, }, - new FillFlowContainer + MapperContainer = new FillFlowContainer { Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, Children = getMapper(metadata) }, - new FillFlowContainer + InfoLabelContainer = new FillFlowContainer { Margin = new MarginPadding { Top = 20 }, Spacing = new Vector2(20, 0), From 2313ff0ddbe0b04c04beda6fe4df5947ec32711f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 22:19:11 +0900 Subject: [PATCH 04/31] Fix beatmap info wedge not showing up when zero beatmaps are loaded Closes #1722. --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index ff1dd95eac..e0fcba5b3c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -509,7 +509,7 @@ namespace osu.Game.Screens.Select currentY += DrawHeight / 2; scrollableContent.Height = currentY; - if (selectedBeatmapSet != null && selectedBeatmapSet.State.Value != CarouselItemState.Selected) + if (selectedBeatmapSet == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3ef6ceeaeb..1baacb78ee 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -66,6 +66,8 @@ namespace osu.Game.Screens.Select Depth = info?.Depth + 1 ?? 0, }, newInfo => { + State = beatmap == null ? Visibility.Hidden : Visibility.Visible; + // ensure we ourselves are visible if not already. if (!IsPresent) this.FadeIn(250); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..9a7dbf002e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -399,7 +399,6 @@ namespace osu.Game.Screens.Select backgroundModeBeatmap.FadeTo(1, 250); } - beatmapInfoWedge.State = Visibility.Visible; beatmapInfoWedge.UpdateBeatmap(beatmap); } From 6a8fd74e055bd3a35931c1112c86298e4cd6f91f Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 17:38:22 +0100 Subject: [PATCH 05/31] fix failing tests 1) waiting for loading to finish so Drawables are all present to do asserts on 2) fix NullRef in ResultPage because of removed line in DummyWorkingBeatmap (author one) --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 8 ++++++++ osu.Game/Screens/Ranking/ResultsPageScore.cs | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 353f351a54..1ef6291ee4 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -20,6 +20,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseBeatmapInfoWedge : OsuTestCase { + private RulesetStore rulesets; private TestBeatmapInfoWedge infoWedge; private readonly List beatmaps = new List(); private readonly Bindable beatmap = new Bindable(); @@ -27,7 +28,14 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase game, RulesetStore rulesets) { + this.rulesets = rulesets; + beatmap.BindTo(game.Beatmap); + } + + protected override void LoadComplete() + { + base.LoadComplete(); Add(infoWedge = new TestBeatmapInfoWedge { diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 911b688669..396d7f3c18 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -324,7 +324,14 @@ namespace osu.Game.Screens.Ranking title.Colour = artist.Colour = colours.BlueDarker; versionMapper.Colour = colours.Gray8; - versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.Metadata.Author.Username}"; + var creator = beatmap.Metadata.Author?.Username; + if (!string.IsNullOrEmpty(creator)) { + versionMapper.Text = $"mapped by {creator}"; + + if (!string.IsNullOrEmpty(beatmap.Version)) + versionMapper.Text = $"{beatmap.Version} - " + versionMapper.Text; + } + title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title); artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist); } From 49e855a29ae3d4538d618e7c6de255e4afa29741 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 23 Dec 2017 11:56:53 +0100 Subject: [PATCH 06/31] finished up visual tests --- .../Visual/TestCaseBeatmapInfoWedge.cs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 1ef6291ee4..61c904aa60 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -68,11 +68,15 @@ namespace osu.Game.Tests.Visual var name = rulesetInfo.ShortName; selectBeatmap(name); - // TODO: check InfoLabels of other rulesets + // TODO: adjust cases once more info is shown for other gamemodes switch (ruleset) { case OsuRuleset osu: testOsuBeatmap(osu); + testInfoLabels(5); + break; + default: + testInfoLabels(2); break; } } @@ -86,7 +90,12 @@ namespace osu.Game.Tests.Visual AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist"); AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Text == $"{ruleset.ShortName}Author")); - // TODO: check InfoLabels + } + + private void testInfoLabels(int expectedCount) + { + AddAssert("check infolabels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check infolabels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount); } private void testNullBeatmap() @@ -96,7 +105,7 @@ namespace osu.Game.Tests.Visual AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist); AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); - AddAssert("check empty infos", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); } private void selectBeatmap(string name) @@ -119,6 +128,10 @@ namespace osu.Game.Tests.Visual private Beatmap createTestBeatmap(RulesetInfo ruleset) { + List objects = new List(); + for (double i = 0; i < 50000; i += 1000) + objects.Add(new HitObject { StartTime = i }); + return new Beatmap { BeatmapInfo = new BeatmapInfo @@ -134,7 +147,7 @@ namespace osu.Game.Tests.Visual StarDifficulty = 6, Version = $"{ruleset.ShortName}Version" }, - HitObjects = new List() // TODO: Fill it with something depending on ruleset? + HitObjects = objects }; } From 68d76d4380f2816088cd7f0344331e79aa4df907 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 23 Dec 2017 20:58:09 +0900 Subject: [PATCH 07/31] Fix taiko strong hits not being handled --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d960ab6b48..c397ea47ef 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { judgementOccurred = false; - if (AllJudged || State != ArmedState.Idle) + if (AllJudged) return false; if (NestedHitObjects != null) From cf316b3c51661a7a21ae1b47c90b9f169c19b8f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 15:39:25 +0900 Subject: [PATCH 08/31] Add tests for initial load states of PlaySongSelect --- .../Visual/TestCasePlaySongSelect.cs | 48 ++++++++++++++++--- osu.Game/Screens/Select/BeatmapCarousel.cs | 1 - osu.Game/Screens/Select/SongSelect.cs | 34 ++++++------- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 6435df7c2c..34b99c6ca6 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -26,6 +26,7 @@ namespace osu.Game.Tests.Visual private RulesetStore rulesets; private DependencyContainer dependencies; + private WorkingBeatmap defaultBeatmap; public override IReadOnlyList RequiredTypes => new[] { @@ -47,10 +48,16 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + private class TestSongSelect : PlaySongSelect + { + public WorkingBeatmap CurrentBeatmap => Beatmap.Value; + public new BeatmapCarousel Carousel => base.Carousel; + } + [BackgroundDependencyLoader] private void load(BeatmapManager baseManager) { - PlaySongSelect songSelect; + TestSongSelect songSelect = null; if (manager == null) { @@ -64,14 +71,43 @@ namespace osu.Game.Tests.Visual dependencies.Cache(rulesets = new RulesetStore(contextFactory)); dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) { - DefaultBeatmap = baseManager.GetWorkingBeatmap(null) + DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) }); - - for (int i = 0; i < 100; i += 10) - manager.Import(createTestBeatmapSet(i)); } - Add(songSelect = new PlaySongSelect()); + void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () => + { + if (deleteMaps) manager.DeleteAll(); + + if (songSelect != null) + { + Remove(songSelect); + songSelect.Dispose(); + } + + Add(songSelect = new TestSongSelect()); + }); + + loadNewSongSelect(true); + + AddWaitStep(1); + + AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); + + AddStep("import test maps", () => + { + for (int i = 0; i < 100; i += 10) + manager.Import(createTestBeatmapSet(i)); + }); + + AddWaitStep(1); + AddStep("select random", () => songSelect.Carousel.SelectNextRandom()); + + AddWaitStep(1); + AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); + + loadNewSongSelect(); + AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index bfba9a7d6b..b4ca6f10f9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -142,7 +142,6 @@ namespace osu.Game.Screens.Select if (newSet == null) { itemsCache.Invalidate(); - SelectNext(); return; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9a7dbf002e..a15699d97a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select protected Container LeftContent; - private readonly BeatmapCarousel carousel; + protected readonly BeatmapCarousel Carousel; private readonly BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; private BeatmapManager beatmaps; @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Select Right = left_area_padding * 2, } }, - carousel = new BeatmapCarousel + Carousel = new BeatmapCarousel { RelativeSizeAxes = Axes.Y, Size = new Vector2(carousel_width, 1), @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, Height = filter_height, - FilterChanged = c => carousel.Filter(c), + FilterChanged = c => Carousel.Filter(c), Exit = Exit, }, beatmapInfoWedge = new BeatmapInfoWedge @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Select Right = left_area_padding, }, }, - new ResetScrollContainer(() => carousel.ScrollToSelected()) + new ResetScrollContainer(() => Carousel.ScrollToSelected()) { RelativeSizeAxes = Axes.Y, Width = 250, @@ -190,15 +190,15 @@ namespace osu.Game.Screens.Select initialAddSetsTask = new CancellationTokenSource(); - carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); + Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); - Beatmap.DisabledChanged += disabled => carousel.AllowSelection = !disabled; + Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; Beatmap.TriggerChange(); Beatmap.ValueChanged += b => { if (IsCurrentScreen) - carousel.SelectBeatmap(b?.BeatmapInfo); + Carousel.SelectBeatmap(b?.BeatmapInfo); }; } @@ -212,9 +212,9 @@ namespace osu.Game.Screens.Select { // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). - carousel.FlushPendingFilterOperations(); + Carousel.FlushPendingFilterOperations(); - carousel.SelectBeatmap(beatmap); + Carousel.SelectBeatmap(beatmap); if (selectionChangedDebounce?.Completed == false) { @@ -282,9 +282,9 @@ namespace osu.Game.Screens.Select private void triggerRandom() { if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed) - carousel.SelectPreviousRandom(); + Carousel.SelectPreviousRandom(); else - carousel.SelectNextRandom(); + Carousel.SelectNextRandom(); } protected override void OnEntering(Screen last) @@ -416,17 +416,17 @@ namespace osu.Game.Screens.Select } } - private void onBeatmapSetAdded(BeatmapSetInfo s) => carousel.UpdateBeatmapSet(s); - private void onBeatmapSetRemoved(BeatmapSetInfo s) => carousel.RemoveBeatmapSet(s); - private void onBeatmapRestored(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); - private void onBeatmapHidden(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); + private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); + private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void carouselBeatmapsLoaded() { if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) - carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); + Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); else - carousel.SelectNextRandom(); + Carousel.SelectNextRandom(); } private void delete(BeatmapSetInfo beatmap) From a04ebd0595e423c02e38b57b5e386020d19f7157 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 15:39:44 +0900 Subject: [PATCH 09/31] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 08f85f9bf9..64e04b9ff2 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 08f85f9bf9a7376aec8dfcde8c7c96d267d8c295 +Subproject commit 64e04b9ff2d5ba53e5c3a46cfa42a79baeffc014 From 482e10966cfb5fd80c892695bfda6f250b6ae4ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 17:02:46 +0900 Subject: [PATCH 10/31] Ensure a selection is made on entering song select if no selection is current --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 3 --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 34b99c6ca6..87f71d215b 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -100,9 +100,6 @@ namespace osu.Game.Tests.Visual manager.Import(createTestBeatmapSet(i)); }); - AddWaitStep(1); - AddStep("select random", () => songSelect.Carousel.SelectNextRandom()); - AddWaitStep(1); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index b4ca6f10f9..c33993c68c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -75,7 +75,8 @@ namespace osu.Game.Screens.Select scrollableContent.Clear(false); itemsCache.Invalidate(); scrollPositionCache.Invalidate(); - BeatmapSetsChanged?.Invoke(); + + Schedule(() => BeatmapSetsChanged?.Invoke()); })); } } @@ -154,6 +155,7 @@ namespace osu.Game.Screens.Select select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet); itemsCache.Invalidate(); + Schedule(() => BeatmapSetsChanged?.Invoke()); }); } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a15699d97a..75c4a68388 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -423,7 +423,7 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) + if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false) Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); else Carousel.SelectNextRandom(); From a7ee6985b050fbf6df3f2880c87f7a1085cec863 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 01:06:33 +0900 Subject: [PATCH 11/31] Add wait step --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 87f71d215b..e27e786a05 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -104,6 +104,7 @@ namespace osu.Game.Tests.Visual AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); loadNewSongSelect(); + AddWaitStep(1); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); From 8529eb1d3a2350da13d8fb445a7d13375afa1c97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 14:49:39 +0900 Subject: [PATCH 12/31] Make strong hit misses not count as misses --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 81b23af1a9..07f7b83cef 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (timeOffset > second_hit_window) - AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.Miss }); + AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.None }); return; } From 844e39a9f6f177be8bc4f41fe8ff69425052d622 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:04:22 +0900 Subject: [PATCH 13/31] Make Swells play samples while they're being hit --- .../Objects/Drawables/DrawableSwell.cs | 37 ++++++++++++++----- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 28 +++++++++++++- .../Objects/SwellSampleMapping.cs | 28 ++++++++++++++ .../osu.Game.Rulesets.Taiko.csproj | 1 + 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 738902846b..d657598554 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,6 +14,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; +using osu.Framework.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -34,10 +35,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private readonly CircularContainer targetRing; private readonly CircularContainer expandingRing; - private readonly TaikoAction[] rimActions = { TaikoAction.LeftRim, TaikoAction.RightRim }; - private readonly TaikoAction[] centreActions = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; - private TaikoAction[] lastAction; - /// /// The amount of times the user has hit this swell. /// @@ -120,11 +117,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, AudioManager audio) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); + + foreach (var mapping in HitObject.ProgressionSamples) + mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -205,22 +205,39 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } + private bool? lastWasCentre; + public override bool OnPressed(TaikoAction action) { // Don't handle keys before the swell starts if (Time.Current < HitObject.StartTime) return false; - // Find the keyset which this key corresponds to - var keySet = rimActions.Contains(action) ? rimActions : centreActions; + var isCentre = action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre; - // Ensure alternating keysets - if (keySet == lastAction) + // Ensure alternating centre and rim hits + if (lastWasCentre == isCentre) return false; - lastAction = keySet; + lastWasCentre = isCentre; UpdateJudgement(true); + if (AllJudged) + return true; + + // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects + // This causes the playfield to not play sounds, so they need to be handled locally + + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; + + var mapping = HitObject.ProgressionSamples[mappingIndex]; + if (isCentre) + mapping.CentreChannel.Play(); + else + mapping.RimChannel.Play(); + return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index f74a543ca9..b4fa736045 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,6 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Taiko.Objects @@ -15,5 +20,26 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; + + public List ProgressionSamples = new List(); + + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + + var progressionSamplePoints = + new[] { controlPointInfo.SamplePointAt(StartTime) } + .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); + + foreach (var point in progressionSamplePoints) + { + ProgressionSamples.Add(new SwellSampleMapping + { + Time = point.Time, + Centre = point.GetSampleInfo(), + Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) + }); + } + } } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs new file mode 100644 index 0000000000..99d0e1d0fd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; + +namespace osu.Game.Rulesets.Taiko.Objects +{ + public class SwellSampleMapping : IComparable + { + public double Time; + public SampleInfo Centre; + public SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index bb02db62b9..9fa3936153 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -74,6 +74,7 @@ + From d288d8a51f370a6f91141c046ad3a67b4a1a6c5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:35:28 +0900 Subject: [PATCH 14/31] Remove SampleInfoList --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++--- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 3 ++- .../Legacy/EndTimeObjectPatternGenerator.cs | 3 ++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 6 +++--- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 3 ++- .../Tests/TestCaseTaikoPlayfield.cs | 14 ++++++++++++-- osu.Game/Audio/SampleInfoList.cs | 18 ------------------ osu.Game/Rulesets/Objects/HitObject.cs | 2 +- .../Legacy/Catch/ConvertHitObjectParser.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 8 ++++---- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Legacy/Mania/ConvertHitObjectParser.cs | 2 +- .../Legacy/Osu/ConvertHitObjectParser.cs | 4 ++-- .../Legacy/Taiko/ConvertHitObjectParser.cs | 4 ++-- osu.Game/Rulesets/Objects/Types/IHasRepeats.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 18 files changed, 41 insertions(+), 47 deletions(-) delete mode 100644 osu.Game/Audio/SampleInfoList.cs diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 8e496c3b0c..7d0d80a0ce 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = lastTickTime, ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = repeatStartTime + t, ComboColour = ComboColour, X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Catch.Objects set { Curve.ControlPoints = value; } } - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public CurveType CurveType { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d5a799b4ed..407d4db143 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 270c264e0c..8251dea5f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -435,7 +436,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3e9fc1ae27..8e832960df 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; using osu.Game.Rulesets.Objects; @@ -77,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy }; if (hold.Head.Samples == null) - hold.Head.Samples = new SampleInfoList(); + hold.Head.Samples = new List(); hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4f5a44e61d..5f9f11c783 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public int RepeatCount { get; set; } = 1; private int stackHeight; @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(RepeatSamples[repeat]) + Samples = new List(RepeatSamples[repeat]) }); } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 9b4a6c47a9..690b80b12c 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps var curveData = obj as IHasCurve; // Old osu! used hit sounding to determine various hit type information - SampleInfoList samples = obj.Samples; + List samples = obj.Samples; bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH); @@ -115,12 +115,12 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List allSamples = curveData != null ? curveData.RepeatSamples : new List(new[] { samples }); + List> allSamples = curveData != null ? curveData.RepeatSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { - SampleInfoList currentSamples = allSamples[i]; + List currentSamples = allSamples[i]; bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH); diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 4104b59979..5a566fd091 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Objects.Types; using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs index bca4806108..b1e6e9c4ce 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs @@ -165,11 +165,15 @@ namespace osu.Game.Rulesets.Taiko.Tests private void addSwell(double duration = default_duration) { - rulesetContainer.Playfield.Add(new DrawableSwell(new Swell + var swell = new Swell { StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, Duration = duration, - })); + }; + + swell.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + rulesetContainer.Playfield.Add(new DrawableSwell(swell)); } private void addDrumRoll(bool strong, double duration = default_duration) @@ -184,6 +188,8 @@ namespace osu.Game.Rulesets.Taiko.Tests Duration = duration, }; + d.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + rulesetContainer.Playfield.Add(new DrawableDrumRoll(d)); } @@ -195,6 +201,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h)); else @@ -209,6 +217,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h)); else diff --git a/osu.Game/Audio/SampleInfoList.cs b/osu.Game/Audio/SampleInfoList.cs deleted file mode 100644 index 06dd716a4a..0000000000 --- a/osu.Game/Audio/SampleInfoList.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; - -namespace osu.Game.Audio -{ - public class SampleInfoList : List - { - public SampleInfoList() - { - } - - public SampleInfoList(IEnumerable elements) : base(elements) - { - } - } -} \ No newline at end of file diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index e950516bf4..56f7a2e1a2 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public SampleInfoList Samples; + public List Samples; [JsonIgnore] public SampleControlPoint SampleControlPoint; diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 667f921e04..fbf02f5345 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 0d7d617405..bdbd7a9e65 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } // Generate the final per-node samples - var nodeSamples = new List(nodes); + var nodeSamples = new List>(nodes); for (int i = 0; i <= repeatCount; i++) nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider repeat count. /// The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples); /// /// Creates a legacy Spinner-type hit object. @@ -234,9 +234,9 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The hold end time. protected abstract HitObject CreateHold(Vector2 position, bool newCombo, double endTime); - private SampleInfoList convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) + private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { - var soundTypes = new SampleInfoList + var soundTypes = new List { new SampleInfo { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 698b74cc28..6dc8a07630 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance { get; set; } - public List RepeatSamples { get; set; } + public List> RepeatSamples { get; set; } public int RepeatCount { get; set; } = 1; public double EndTime => StartTime + RepeatCount * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 86dd40b06e..2060b84222 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index 24c205db13..0062d29446 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Osu { @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index 0554cfd97d..529a28ac15 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Taiko { @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 5abad2d661..2fe2424d49 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Types /// /// The samples to be played when each repeat node is hit (0 -> first repeat node, 1 -> second repeat node, etc). /// - List RepeatSamples { get; } + List> RepeatSamples { get; } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..1c5d20842d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,7 +239,6 @@ - From 0fb620a8d3c730da1f10d1d5ab45482d783a3b2d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:41:18 +0900 Subject: [PATCH 15/31] Make HitObject.Samples non-nullable --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++-- osu.Game/Rulesets/Objects/HitObject.cs | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index c397ea47ef..be161b9ad3 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -84,10 +84,11 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (HitObject.Samples != null) + if (Samples.Count > 0) { if (HitObject.SampleControlPoint == null) - throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SampleControlPoint)}."); + throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); foreach (SampleInfo s in HitObject.Samples) { diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 56f7a2e1a2..4f06f6afe1 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Objects /// public virtual double StartTime { get; set; } + private List samples; + /// /// The samples to be played when this hit object is hit. /// @@ -32,7 +34,11 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public List Samples; + public List Samples + { + get => samples ?? (samples = new List()); + set => samples = value; + } [JsonIgnore] public SampleControlPoint SampleControlPoint; From 8bfdee586b6cde7effbc17b8c3ae6b7ed1ae4dec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:47:29 +0900 Subject: [PATCH 16/31] Rename SwellSampleMapping -> DrumSampleMapping --- .../Audio/DrumSampleMapping.cs | 40 +++++++++++++++++++ .../Objects/Drawables/DrawableSwell.cs | 3 +- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 15 ++----- .../Objects/SwellSampleMapping.cs | 28 ------------- .../osu.Game.Rulesets.Taiko.csproj | 2 +- 5 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs delete mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs new file mode 100644 index 0000000000..25fa9951df --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; + +namespace osu.Game.Rulesets.Taiko.Audio +{ + public class DrumSampleMapping : IComparable + { + public double Time; + public readonly SampleInfo Centre; + public readonly SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public DrumSampleMapping() + { + } + + public DrumSampleMapping(SampleControlPoint samplePoint) + { + Time = samplePoint.Time; + Centre = samplePoint.GetSampleInfo(); + Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); + } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index d657598554..5131572abd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -15,6 +15,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; using osu.Framework.Audio; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -228,7 +229,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects // This causes the playfield to not play sounds, so they need to be handled locally - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); if (mappingIndex < 0) mappingIndex = ~mappingIndex - 1; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index b4fa736045..849c88ee4d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -7,6 +7,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { @@ -21,25 +22,17 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public int RequiredHits = 10; - public List ProgressionSamples = new List(); + public List ProgressionSamples = new List(); protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - var progressionSamplePoints = - new[] { controlPointInfo.SamplePointAt(StartTime) } + var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); foreach (var point in progressionSamplePoints) - { - ProgressionSamples.Add(new SwellSampleMapping - { - Time = point.Time, - Centre = point.GetSampleInfo(), - Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) - }); - } + ProgressionSamples.Add(new DrumSampleMapping(point)); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs deleted file mode 100644 index 99d0e1d0fd..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Game.Audio; - -namespace osu.Game.Rulesets.Taiko.Objects -{ - public class SwellSampleMapping : IComparable - { - public double Time; - public SampleInfo Centre; - public SampleInfo Rim; - - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public void RetrieveChannels(AudioManager audio) - { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); - } - - public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); - } -} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 9fa3936153..f1c29c1a34 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -44,6 +44,7 @@ + @@ -74,7 +75,6 @@ - From ac8b345bfebba4530c67bbf9d0087472825ace18 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:20 +0900 Subject: [PATCH 17/31] Make TaikoPlayfield use the new DrumSampleMapping --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 37 +++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 2cc95fc981..96ef86e3ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -23,6 +23,7 @@ using osu.Framework.Audio.Sample; using System.Collections.Generic; using osu.Game.Audio; using System; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; private readonly ControlPointInfo controlPointInfo; - private Dictionary drumSampleMappings; + private readonly List drumSampleMappings = new List(); public TaikoPlayfield(ControlPointInfo controlPointInfo) : base(Axes.X) @@ -207,15 +208,16 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - drumSampleMappings = new Dictionary(); - foreach (var s in controlPointInfo.SamplePoints) + // We may have 0 sample points, but we need at least the default one + var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } + .Concat(controlPointInfo.SamplePoints); + + foreach (var s in samplePoints) { - drumSampleMappings.Add(s, - new DrumSamples - { - Centre = s.GetSampleInfo().GetChannel(audio.Sample), - Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) - }); + var mapping = new DrumSampleMapping(s); + mapping.RetrieveChannels(audio); + + drumSampleMappings.Add(mapping); } overlayBackgroundContainer.BorderColour = colours.Gray0; @@ -285,25 +287,20 @@ namespace osu.Game.Rulesets.Taiko.UI public bool OnPressed(TaikoAction action) { - var samplePoint = controlPointInfo.SamplePointAt(Clock.CurrentTime); + var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; - if (!drumSampleMappings.TryGetValue(samplePoint, out var samples)) - throw new InvalidOperationException("Current sample set not found."); + var mapping = drumSampleMappings[mappingIndex]; if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - samples.Centre.Play(); + mapping.CentreChannel.Play(); else - samples.Rim.Play(); + mapping.RimChannel.Play(); return true; } public bool OnReleased(TaikoAction action) => false; - - private class DrumSamples - { - public SampleChannel Centre; - public SampleChannel Rim; - } } } From affdd81563b21d0fdfec753bc2dcdc46cb417ad9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:44 +0900 Subject: [PATCH 18/31] Remove unused usings --- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 1 - osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 849c88ee4d..714e5d29ee 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 96ef86e3ce..229e44cf27 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -19,10 +19,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using System.Collections.Generic; -using osu.Game.Audio; -using System; using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI From 3c8d30f8e67158ce5b105ce28eff9b726aa09093 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 00:37:50 +0900 Subject: [PATCH 19/31] Add a dialog offering to import beatmaps from stable --- osu.Game/Beatmaps/BeatmapManager.cs | 6 ++-- .../Sections/Maintenance/GeneralSettings.cs | 3 +- .../Screens/Select/ImportFromStablePopup.cs | 33 +++++++++++++++++++ osu.Game/Screens/Select/PlaySongSelect.cs | 15 +++++++-- osu.Game/osu.Game.csproj | 1 + 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Screens/Select/ImportFromStablePopup.cs diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 0325785016..c86860f7b0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -697,10 +697,12 @@ namespace osu.Game.Beatmaps } } + public bool StableInstallationAvailable => GetStableStorage?.Invoke() != null; + /// /// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future. /// - public void ImportFromStable() + public async Task ImportFromStable() { var stable = GetStableStorage?.Invoke(); @@ -710,7 +712,7 @@ namespace osu.Game.Beatmaps return; } - Import(stable.GetDirectories("Songs")); + await Task.Factory.StartNew(() => Import(stable.GetDirectories("Songs")), TaskCreationOptions.LongRunning); } public void DeleteAll() diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index e288445c6d..9ab4143613 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -30,8 +30,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Action = () => { importButton.Enabled.Value = false; - Task.Factory.StartNew(beatmaps.ImportFromStable) - .ContinueWith(t => Schedule(() => importButton.Enabled.Value = true), TaskContinuationOptions.LongRunning); + beatmaps.ImportFromStable().ContinueWith(t => Schedule(() => importButton.Enabled.Value = true)); } }, deleteButton = new DangerousSettingsButton diff --git a/osu.Game/Screens/Select/ImportFromStablePopup.cs b/osu.Game/Screens/Select/ImportFromStablePopup.cs new file mode 100644 index 0000000000..489ab79fa4 --- /dev/null +++ b/osu.Game/Screens/Select/ImportFromStablePopup.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Screens.Select +{ + public class ImportFromStablePopup : PopupDialog + { + public ImportFromStablePopup(Action importFromStable) + { + HeaderText = @"You have no beatmaps!"; + BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps?"; + + Icon = FontAwesome.fa_trash_o; + + Buttons = new PopupDialogButton[] + { + new PopupDialogOkButton + { + Text = @"Yes please!", + Action = importFromStable + }, + new PopupDialogCancelButton + { + Text = @"No, I'd like to start from scratch", + }, + }; + } + } +} diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 4a0ee31fbb..727cdb9959 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Screens.Edit; using osu.Game.Screens.Play; @@ -45,8 +46,8 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; - [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay) { sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); @@ -59,6 +60,16 @@ namespace osu.Game.Screens.Select ValidForResume = false; Push(new Editor()); }, Key.Number3); + + if (dialogOverlay != null) + { + Schedule(() => + { + // if we have no beatmaps but osu-stable is found, let's prompt the user to import. + if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable) + dialogOverlay.Push(new ImportFromStablePopup(() => beatmaps.ImportFromStable())); + }); + } } protected override void UpdateBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..fa25fa7048 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -310,6 +310,7 @@ + From 798c2c66667cdb7f5b2c54d59731d3ae71486894 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 12:57:45 +0900 Subject: [PATCH 20/31] Add special logic to song select to avoid obvious clipping when notifications are displayed Not sure if we will keep this going forward (there will likely be an opaque tab control on the notifications overlay similar to options) but let's go with this for now. --- osu.Game/Screens/Select/FilterControl.cs | 4 +- osu.Game/Screens/Select/SongSelect.cs | 48 +++++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 1b86cec613..2dbd63f77b 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Select { Children = new Drawable[] { - new Box + Background = new Box { Colour = Color4.Black, Alpha = 0.8f, @@ -167,6 +167,8 @@ namespace osu.Game.Screens.Select private Bindable showConverted; + public readonly Box Background; + [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuColour colours, OsuGame osu, OsuConfigManager config) { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..8189624ce1 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -103,21 +103,41 @@ namespace osu.Game.Screens.Select Right = left_area_padding * 2, } }, - carousel = new BeatmapCarousel + new Container { - RelativeSizeAxes = Axes.Y, - Size = new Vector2(carousel_width, 1), - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - SelectionChanged = carouselSelectionChanged, - BeatmapSetsChanged = carouselBeatmapsLoaded, - }, - FilterControl = new FilterControl - { - RelativeSizeAxes = Axes.X, - Height = filter_height, - FilterChanged = c => carousel.Filter(c), - Exit = Exit, + RelativeSizeAxes = Axes.Both, + Masking = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 2, //avoid horizontal masking so the panels don't clip when screen stack is pushed. + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 0.5f, + Children = new Drawable[] + { + carousel = new BeatmapCarousel + { + Masking = false, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(carousel_width, 1), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + SelectionChanged = carouselSelectionChanged, + BeatmapSetsChanged = carouselBeatmapsLoaded, + }, + FilterControl = new FilterControl + { + RelativeSizeAxes = Axes.X, + Height = filter_height, + FilterChanged = c => carousel.Filter(c), + Background = { Width = 2 }, + Exit = Exit, + }, + } + }, }, beatmapInfoWedge = new BeatmapInfoWedge { From 14162b5d46a56f4f8da0e01829c25c67c331b1e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:23 +0900 Subject: [PATCH 21/31] Make InputDrum handle all Normals/Claps, hitobjects all others --- .../Audio/DrumSampleMapping.cs | 47 +++++++++++-------- .../Objects/Drawables/DrawableSwell.cs | 19 -------- .../Drawables/DrawableTaikoHitObject.cs | 7 +++ osu.Game.Rulesets.Taiko/Objects/Swell.cs | 13 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 36 ++++++++++++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 38 ++------------- .../Objects/Drawables/DrawableHitObject.cs | 6 ++- 7 files changed, 72 insertions(+), 94 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index 25fa9951df..9d0037b97a 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -1,7 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; +using System.Collections.Generic; +using System.Linq; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Game.Audio; @@ -9,32 +10,38 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Taiko.Audio { - public class DrumSampleMapping : IComparable + public class DrumSampleMapping { - public double Time; - public readonly SampleInfo Centre; - public readonly SampleInfo Rim; + private readonly ControlPointInfo controlPoints; + private readonly Dictionary mappings = new Dictionary(); - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public DrumSampleMapping() + public DrumSampleMapping(ControlPointInfo controlPoints, AudioManager audio) { + this.controlPoints = controlPoints; + + IEnumerable samplePoints; + if (controlPoints.SamplePoints.Count == 0) + // Get the default sample point + samplePoints = new[] { controlPoints.SamplePointAt(double.MinValue) }; + else + samplePoints = controlPoints.SamplePoints; + + foreach (var s in samplePoints.Distinct()) + { + mappings[s] = new DrumSample + { + Centre = s.GetSampleInfo().GetChannel(audio.Sample), + Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) + }; + } } - public DrumSampleMapping(SampleControlPoint samplePoint) - { - Time = samplePoint.Time; - Centre = samplePoint.GetSampleInfo(); - Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); - } + public DrumSample SampleAt(double time) => mappings[controlPoints.SamplePointAt(time)]; - public void RetrieveChannels(AudioManager audio) + public class DrumSample { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); + public SampleChannel Centre; + public SampleChannel Rim; } - - public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5131572abd..3099c6984c 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -123,9 +123,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); - - foreach (var mapping in HitObject.ProgressionSamples) - mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -223,22 +220,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables UpdateJudgement(true); - if (AllJudged) - return true; - - // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects - // This causes the playfield to not play sounds, so they need to be handled locally - - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = HitObject.ProgressionSamples[mappingIndex]; - if (isCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 7976cbbbc1..cf0df260b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,6 +6,10 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; +using System; +using System.Linq; +using osu.Game.Audio; +using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -35,6 +39,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.KiaiMode = HitObject.Kiai; } + // Normal and clap samples are handled by the drum + protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP); + protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); public abstract bool OnPressed(TaikoAction action); diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 714e5d29ee..95ea9f8aa4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -20,18 +20,5 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; - - public List ProgressionSamples = new List(); - - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - - var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } - .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); - - foreach (var point in progressionSamplePoints) - ProgressionSamples.Add(new DrumSampleMapping(point)); - } } } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 5e79166bec..8c02b21733 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,14 +2,20 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using System.Linq; using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -18,16 +24,26 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class InputDrum : Container { - public InputDrum() + private const float middle_split = 0.025f; + + private readonly ControlPointInfo controlPoints; + + public InputDrum(ControlPointInfo controlPoints) { + this.controlPoints = controlPoints; + RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; + } - const float middle_split = 0.025f; + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + var sampleMappings = new DrumSampleMapping(controlPoints, audio); Children = new Drawable[] { - new TaikoHalfDrum(false) + new TaikoHalfDrum(false, sampleMappings) { Name = "Left Half", Anchor = Anchor.Centre, @@ -38,7 +54,7 @@ namespace osu.Game.Rulesets.Taiko.UI RimAction = TaikoAction.LeftRim, CentreAction = TaikoAction.LeftCentre }, - new TaikoHalfDrum(true) + new TaikoHalfDrum(true, sampleMappings) { Name = "Right Half", Anchor = Anchor.Centre, @@ -72,8 +88,12 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Sprite centre; private readonly Sprite centreHit; - public TaikoHalfDrum(bool flipped) + private readonly DrumSampleMapping sampleMappings; + + public TaikoHalfDrum(bool flipped, DrumSampleMapping sampleMappings) { + this.sampleMappings = sampleMappings; + Masking = true; Children = new Drawable[] @@ -128,15 +148,21 @@ namespace osu.Game.Rulesets.Taiko.UI Drawable target = null; Drawable back = null; + var drumSample = sampleMappings.SampleAt(Time.Current); + if (action == CentreAction) { target = centreHit; back = centre; + + drumSample.Centre.Play(); } else if (action == RimAction) { target = rimHit; back = rim; + + drumSample.Rim.Play(); } if (target != null) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 229e44cf27..14f8de0f48 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -24,7 +24,7 @@ using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield, IKeyBindingHandler + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -59,13 +59,9 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box overlayBackground; private readonly Box background; - private readonly ControlPointInfo controlPointInfo; - private readonly List drumSampleMappings = new List(); - - public TaikoPlayfield(ControlPointInfo controlPointInfo) + public TaikoPlayfield(ControlPointInfo controlPoints) : base(Axes.X) { - this.controlPointInfo = controlPointInfo; AddRangeInternal(new Drawable[] { backgroundContainer = new Container @@ -158,7 +154,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - new InputDrum + new InputDrum(controlPoints) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -205,17 +201,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - // We may have 0 sample points, but we need at least the default one - var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } - .Concat(controlPointInfo.SamplePoints); - foreach (var s in samplePoints) - { - var mapping = new DrumSampleMapping(s); - mapping.RetrieveChannels(audio); - - drumSampleMappings.Add(mapping); - } overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1; @@ -281,23 +267,5 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); } } - - public bool OnPressed(TaikoAction action) - { - var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = drumSampleMappings[mappingIndex]; - - if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - - return true; - } - - public bool OnReleased(TaikoAction action) => false; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index be161b9ad3..ab4c04be3f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -72,6 +72,7 @@ namespace osu.Game.Rulesets.Objects.Drawables public IReadOnlyList Judgements => judgements; protected List Samples = new List(); + protected virtual IEnumerable GetSamples() => HitObject.Samples; public readonly Bindable State = new Bindable(); @@ -84,13 +85,14 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (Samples.Count > 0) + var samples = GetSamples(); + if (samples.Any()) { if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - foreach (SampleInfo s in HitObject.Samples) + foreach (SampleInfo s in samples) { SampleInfo localSampleInfo = new SampleInfo { From 35d7fa8a81ae017f964c1644ddac3db0b7f94135 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:38 +0900 Subject: [PATCH 22/31] Cleanup things that are now not needed with these changes --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 2 +- .../Objects/Drawables/DrawableHitStrong.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 4 +--- .../Objects/Drawables/DrawableTaikoHitObject.cs | 1 - osu.Game.Rulesets.Taiko/Objects/Swell.cs | 5 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 3 --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +------- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index df33aae94e..fd35f0eaec 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables validKeyPressed = HitActions.Contains(action); // Only count this as handled if the new judgement is a hit - return UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return UpdateJudgement(true); } protected override void Update() diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 07f7b83cef..cda82afe0e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return false; // Assume the intention was to hit the strong hit with both keys only if the first key is still being held down - return firstKeyHeld && UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return firstKeyHeld && UpdateJudgement(true); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 3099c6984c..5ca33aaea2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,8 +14,6 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; -using osu.Framework.Audio; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -118,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index cf0df260b1..92da3fe09e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,7 +6,6 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; -using System; using System.Linq; using osu.Game.Audio; using System.Collections.Generic; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 95ea9f8aa4..cd2876ea2d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,12 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using System.Linq; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 8c02b21733..bf1274256b 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using System.Linq; using OpenTK; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -12,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; -using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Audio; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 14f8de0f48..3fdbd056ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -16,11 +16,7 @@ using osu.Framework.Extensions.Color4Extensions; using System.Linq; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables; -using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; -using osu.Framework.Audio; -using System.Collections.Generic; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -199,10 +195,8 @@ namespace osu.Game.Rulesets.Taiko.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { - - overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1; From 9ccc49c9b5a2b61c73e30a9cea35118614f5f4fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:32:39 +0900 Subject: [PATCH 23/31] Make selection triggering more liberal --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index e3566f3206..9d7867659d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -513,7 +513,7 @@ namespace osu.Game.Screens.Select currentY += DrawHeight / 2; scrollableContent.Height = currentY; - if (selectedBeatmapSet != null && (selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) + if (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); From e14ad31a071cacfc10f4ab8668f3d00634776c68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:32:53 +0900 Subject: [PATCH 24/31] Increase wait durations for test stability --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index e27e786a05..69aa371958 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual loadNewSongSelect(true); - AddWaitStep(1); + AddWaitStep(3); AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); @@ -100,11 +100,11 @@ namespace osu.Game.Tests.Visual manager.Import(createTestBeatmapSet(i)); }); - AddWaitStep(1); + AddWaitStep(3); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); loadNewSongSelect(); - AddWaitStep(1); + AddWaitStep(3); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); From 024d9a6850c9071225cba706b77e8f21d9f426e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:33:02 +0900 Subject: [PATCH 25/31] Remove unnecessary null check --- .../Visual/TestCasePlaySongSelect.cs | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 69aa371958..18e40db064 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -59,21 +59,18 @@ namespace osu.Game.Tests.Visual { TestSongSelect songSelect = null; - if (manager == null) + var storage = new TestStorage(@"TestCasePlaySongSelect"); + + // this is by no means clean. should be replacing inside of OsuGameBase somehow. + var context = new OsuDbContext(); + + Func contextFactory = () => context; + + dependencies.Cache(rulesets = new RulesetStore(contextFactory)); + dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) { - var storage = new TestStorage(@"TestCasePlaySongSelect"); - - // this is by no means clean. should be replacing inside of OsuGameBase somehow. - var context = new OsuDbContext(); - - Func contextFactory = () => context; - - dependencies.Cache(rulesets = new RulesetStore(contextFactory)); - dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) - { - DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) - }); - } + DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) + }); void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () => { From ed1df94f778d983933e72183a386e0f3bbd1b11d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:48:01 +0900 Subject: [PATCH 26/31] Fix unread light not turning off --- osu.Game/Overlays/Notifications/Notification.cs | 2 +- osu.Game/Overlays/Notifications/SimpleNotification.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 422051364e..b4720e79c4 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -261,4 +261,4 @@ namespace osu.Game.Overlays.Notifications } } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 0b8b365c48..1e691e2a5a 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -83,8 +83,10 @@ namespace osu.Game.Overlays.Notifications set { + if (value == base.Read) return; + base.Read = value; - Light.FadeTo(value ? 1 : 0, 100); + Light.FadeTo(value ? 0 : 1, 100); } } } From 45b3acdd6f1ad89ade0f0abd8564c0fcaa7fefb7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:50:59 +0900 Subject: [PATCH 27/31] Fix progress notifications not closing properly when opening their continuation --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 9211c227f8..c39c630858 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Notifications protected virtual void Completed() { - Expire(); + base.Close(); CompletionTarget?.Invoke(CreateCompletionNotification()); } From 24d8d357d07e762fb233411c5e8860400664f151 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:52:36 +0900 Subject: [PATCH 28/31] Only bounce and flash notification count when increasing --- .../Toolbar/ToolbarNotificationButton.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index faf802f5e7..c093767e52 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -59,16 +59,27 @@ namespace osu.Game.Overlays.Toolbar private class CountCircle : CompositeDrawable { - private readonly OsuSpriteText count; + private readonly OsuSpriteText countText; private readonly Circle circle; + private int count; + public int Count { + get { return count; } set { - count.Text = value.ToString("#,0"); - circle.FlashColour(Color4.White, 600, Easing.OutQuint); - this.ScaleTo(1.1f).Then().ScaleTo(1, 600, Easing.OutElastic); + if (count == value) + return; + + if (value > count) + { + circle.FlashColour(Color4.White, 600, Easing.OutQuint); + this.ScaleTo(1.1f).Then().ScaleTo(1, 600, Easing.OutElastic); + } + + count = value; + countText.Text = value.ToString("#,0"); } } @@ -83,7 +94,7 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.Both, Colour = Color4.Red }, - count = new OsuSpriteText + countText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 44fbe7859a0a703f540f2fa6a70b413665bcb75a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 26 Dec 2017 11:34:26 +0100 Subject: [PATCH 29/31] move anchor and origin so metadata doesn't move if it's partially empty --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 5d4f950a51..4f20b50d35 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -154,9 +154,10 @@ namespace osu.Game.Screens.Select }, new FillFlowContainer { - Name = "Bottom-aligned metadata", - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Name = "Centre-aligned metadata", + Anchor = Anchor.CentreLeft, + Origin = Anchor.TopLeft, + Y = -22, Direction = FillDirection.Vertical, Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 }, AutoSizeAxes = Axes.Both, From 1c4bcdda96f690123a8eb2ae7a502da9cac11a52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 20:13:55 +0900 Subject: [PATCH 30/31] Fix test race condition async loads --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 61c904aa60..53943edfab 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -110,11 +110,15 @@ namespace osu.Game.Tests.Visual private void selectBeatmap(string name) { + var infoBefore = infoWedge.Info; + AddStep($"select {name} beatmap", () => { beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name)); infoWedge.UpdateBeatmap(beatmap); }); + + AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load"); } private void selectNullBeatmap() From 7504cd589dc532f67e1a2c42aac5505732c9c6ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 20:18:47 +0900 Subject: [PATCH 31/31] Move alpha handling to state --- .../Visual/TestCaseBeatmapInfoWedge.cs | 20 +++++++++---------- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 9 ++++++--- osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 53943edfab..3a50e43239 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -41,25 +41,23 @@ namespace osu.Game.Tests.Visual { Size = new Vector2(0.5f, 245), RelativeSizeAxes = Axes.X, - Margin = new MarginPadding - { - Top = 20, - } - }); - - AddStep("hide", () => - { - infoWedge.State = Visibility.Hidden; - Content.FadeOut(100); + Margin = new MarginPadding { Top = 20 } }); AddStep("show", () => { - Content.FadeInFromZero(250); infoWedge.State = Visibility.Visible; infoWedge.UpdateBeatmap(beatmap); }); + AddWaitStep(3); + + AddStep("hide", () => { infoWedge.State = Visibility.Hidden; }); + + AddWaitStep(3); + + AddStep("show", () => { infoWedge.State = Visibility.Visible; }); + foreach (var rulesetInfo in rulesets.AvailableRulesets) { var ruleset = rulesetInfo.CreateInstance(); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 4f20b50d35..d4f1b90ebf 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -35,6 +35,7 @@ namespace osu.Game.Screens.Select Masking = true; BorderColour = new Color4(221, 255, 255, 255); BorderThickness = 2.5f; + Alpha = 0; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, @@ -50,12 +51,14 @@ namespace osu.Game.Screens.Select { this.MoveToX(0, 800, Easing.OutQuint); this.RotateTo(0, 800, Easing.OutQuint); + this.FadeIn(250); } protected override void PopOut() { - this.MoveToX(-100, 800, Easing.InQuint); - this.RotateTo(10, 800, Easing.InQuint); + this.MoveToX(-100, 800, Easing.In); + this.RotateTo(10, 800, Easing.In); + this.FadeOut(500, Easing.In); } public void UpdateBeatmap(WorkingBeatmap beatmap) @@ -68,7 +71,7 @@ namespace osu.Game.Screens.Select { // ensure we ourselves are visible if not already. if (!IsPresent) - this.FadeIn(250); + State = Visibility.Visible; Info?.FadeOut(250); Info?.Expire(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..a66cd0b3e3 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -121,7 +121,6 @@ namespace osu.Game.Screens.Select }, beatmapInfoWedge = new BeatmapInfoWedge { - Alpha = 0, Size = wedged_container_size, RelativeSizeAxes = Axes.X, Margin = new MarginPadding