From 3fdf8dc386125522ce1c025a8d52fc276b987da7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 16:41:52 +0300 Subject: [PATCH 01/43] Recolour main background --- osu.Game/Overlays/ChangelogOverlay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 6a8cb29d3e..d13ac5c2de 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -13,7 +13,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Input.Bindings; using osu.Game.Online.API.Requests; @@ -42,14 +41,14 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colour) + private void load(AudioManager audio) { Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = colour.PurpleDarkAlternative, + Colour = ColourProvider.Background4, }, new OsuScrollContainer { From e9f69d2c23706e3668bb9457f771e9c86955248a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 16:55:12 +0300 Subject: [PATCH 02/43] Adjust date for ChangelogSingleBuild --- osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index 73f9466179..4d2c8346a5 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -80,6 +80,8 @@ namespace osu.Game.Overlays.Changelog { } + private OsuSpriteText date; + protected override FillFlowContainer CreateHeader() { var fill = base.CreateHeader(); @@ -89,11 +91,10 @@ namespace osu.Game.Overlays.Changelog existing.Scale = new Vector2(1.25f); existing.Action = null; - existing.Add(new OsuSpriteText + existing.Add(date = new OsuSpriteText { - Text = Build.CreatedAt.Date.ToString("dd MMM yyyy"), + Text = Build.CreatedAt.Date.ToString("dd MMMM yyyy"), Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 14), - Colour = OsuColour.FromHex(@"FD5"), Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre, Margin = new MarginPadding { Top = 5 }, @@ -113,6 +114,12 @@ namespace osu.Game.Overlays.Changelog return fill; } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + date.Colour = colourProvider.Light1; + } } private class NavigationIconButton : IconButton From 70eb2ed09e6ee46f84708bd9ae228238cd1bc949 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 17:11:29 +0300 Subject: [PATCH 03/43] Adjust ChangelogBuild appearance --- osu.Game/Overlays/Changelog/ChangelogBuild.cs | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index 5a3ce6291e..00bd36649a 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -51,28 +51,27 @@ namespace osu.Game.Overlays.Changelog } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, OverlayColourProvider colourProvider) { foreach (var categoryEntries in Build.ChangelogEntries.GroupBy(b => b.Category).OrderBy(c => c.Key)) { ChangelogEntries.Add(new OsuSpriteText { Text = categoryEntries.Key, - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 24), + Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 18), Margin = new MarginPadding { Top = 35, Bottom = 15 }, }); - var fontLarge = OsuFont.GetFont(size: 18); - var fontMedium = OsuFont.GetFont(size: 14); - var fontSmall = OsuFont.GetFont(size: 12); + var fontLarge = OsuFont.GetFont(size: 16); + var fontMedium = OsuFont.GetFont(size: 12); - foreach (APIChangelogEntry entry in categoryEntries) + foreach (var entry in categoryEntries) { var entryColour = entry.Major ? colours.YellowLight : Color4.White; LinkFlowContainer title; - Container titleContainer = new Container + var titleContainer = new Container { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -83,7 +82,7 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreRight, - Size = new Vector2(fontSmall.Size), + Size = new Vector2(10), Icon = entry.Type == ChangelogEntryType.Fix ? FontAwesome.Solid.Check : FontAwesome.Solid.Plus, Colour = entryColour, Margin = new MarginPadding { Right = 5 }, @@ -123,9 +122,9 @@ namespace osu.Game.Overlays.Changelog }); } - title.AddText(" by ", t => + title.AddText(" by ", t => { - t.Font = fontMedium; + t.Font = fontMedium.With(italics: true); t.Colour = entryColour; }); @@ -137,7 +136,7 @@ namespace osu.Game.Overlays.Changelog Id = entry.GithubUser.UserId.Value }, t => { - t.Font = fontMedium; + t.Font = fontMedium.With(italics: true); t.Colour = entryColour; }); } @@ -145,7 +144,7 @@ namespace osu.Game.Overlays.Changelog { title.AddLink(entry.GithubUser.DisplayName, entry.GithubUser.GithubUrl, t => { - t.Font = fontMedium; + t.Font = fontMedium.With(italics: true); t.Colour = entryColour; }); } @@ -153,7 +152,7 @@ namespace osu.Game.Overlays.Changelog { title.AddText(entry.GithubUser.DisplayName, t => { - t.Font = fontSmall; + t.Font = fontMedium.With(italics: true); t.Colour = entryColour; }); } @@ -162,7 +161,7 @@ namespace osu.Game.Overlays.Changelog if (!string.IsNullOrEmpty(entry.MessageHtml)) { - TextFlowContainer message = new TextFlowContainer + var message = new TextFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -171,8 +170,8 @@ namespace osu.Game.Overlays.Changelog // todo: use markdown parsing once API returns markdown message.AddText(WebUtility.HtmlDecode(Regex.Replace(entry.MessageHtml, @"<(.|\n)*?>", string.Empty)), t => { - t.Font = fontSmall; - t.Colour = new Color4(235, 184, 254, 255); + t.Font = fontMedium; + t.Colour = colourProvider.Foreground1; }); ChangelogEntries.Add(message); From 491906d53416125deb9a753772b7512afe187802 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 17:19:49 +0300 Subject: [PATCH 04/43] Adjust ChangelogListing appearance --- osu.Game/Overlays/Changelog/ChangelogListing.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index 41d8228475..19bc5975f1 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -24,13 +24,13 @@ namespace osu.Game.Overlays.Changelog } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { - DateTime currentDate = DateTime.MinValue; + var currentDate = DateTime.MinValue; if (entries == null) return; - foreach (APIChangelogBuild build in entries) + foreach (var build in entries) { if (build.CreatedAt.Date != currentDate) { @@ -49,10 +49,9 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = 15 }, - Text = build.CreatedAt.Date.ToString("dd MMM yyyy"), + Margin = new MarginPadding { Top = 20 }, + Text = build.CreatedAt.Date.ToString("dd MMMM yyyy"), Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 24), - Colour = OsuColour.FromHex(@"FD5"), }); currentDate = build.CreatedAt.Date; @@ -68,7 +67,7 @@ namespace osu.Game.Overlays.Changelog Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = new Color4(32, 24, 35, 255), + Colour = colourProvider.Background6, } }); } From 48a9b465ef473e8ac5495132a1aac7f46776f94c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 17:22:46 +0300 Subject: [PATCH 05/43] Adjust icons colour --- osu.Game/Overlays/Changelog/ChangelogBuild.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index 00bd36649a..94bb8b5abe 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -16,6 +16,7 @@ using osuTK.Graphics; using osu.Framework.Allocation; using System.Net; using osuTK; +using osu.Framework.Extensions.Color4Extensions; namespace osu.Game.Overlays.Changelog { @@ -84,7 +85,7 @@ namespace osu.Game.Overlays.Changelog Origin = Anchor.CentreRight, Size = new Vector2(10), Icon = entry.Type == ChangelogEntryType.Fix ? FontAwesome.Solid.Check : FontAwesome.Solid.Plus, - Colour = entryColour, + Colour = entryColour.Darken(0.7f), Margin = new MarginPadding { Right = 5 }, }, title = new LinkFlowContainer From c49074dde36776c3c627d2db3b2d30daa03feba3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 17:29:51 +0300 Subject: [PATCH 06/43] Adjust comments placement --- osu.Game/Overlays/Changelog/ChangelogContent.cs | 1 - osu.Game/Overlays/Changelog/ChangelogListing.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs | 13 +++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index 2f6c1ae902..49dd9bb835 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -19,7 +19,6 @@ namespace osu.Game.Overlays.Changelog RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; - Padding = new MarginPadding { Bottom = 50 }; } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index 19bc5975f1..55c79e7e79 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Changelog { RelativeSizeAxes = Axes.X, Height = 2, - Colour = new Color4(17, 17, 17, 255), + Colour = colourProvider.Background6, Margin = new MarginPadding { Top = 30 }, }); } diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index 4d2c8346a5..8b89d63aab 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -31,7 +32,7 @@ namespace osu.Game.Overlays.Changelog } [BackgroundDependencyLoader] - private void load(CancellationToken? cancellation, IAPIProvider api) + private void load(CancellationToken? cancellation, IAPIProvider api, OverlayColourProvider colourProvider) { bool complete = false; @@ -63,10 +64,14 @@ namespace osu.Game.Overlays.Changelog Children = new Drawable[] { new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, - comments = new CommentsContainer + new Box { - Margin = new MarginPadding { Top = 10 } - } + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Top = 30 }, + }, + comments = new CommentsContainer() }; comments.ShowComments(CommentableType.Build, build.Id); From 8593642a045df159c965a2baa6683c1eccd426b2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 18:12:23 +0300 Subject: [PATCH 07/43] Adjust StreamBadgeArea --- .../Overlays/Changelog/UpdateStreamBadge.cs | 125 ++++++++---------- .../Changelog/UpdateStreamBadgeArea.cs | 13 +- 2 files changed, 64 insertions(+), 74 deletions(-) diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs index 52b77604d9..99929058e2 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs +++ b/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs @@ -3,8 +3,6 @@ using Humanizer; using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,99 +14,90 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Changelog { public class UpdateStreamBadge : TabItem { - private const float badge_height = 66.5f; private const float badge_width = 100; private const float transition_duration = 100; - private readonly ExpandingBar expandingBar; - private SampleChannel sampleClick; - private SampleChannel sampleHover; - - private readonly FillFlowContainer text; - public readonly Bindable SelectedTab = new Bindable(); - private readonly Container fadeContainer; + private readonly APIUpdateStream stream; + + private Container fadeContainer; + private FillFlowContainer text; + private ExpandingBar expandingBar; public UpdateStreamBadge(APIUpdateStream stream) : base(stream) { - Size = new Vector2(stream.IsFeatured ? badge_width * 2 : badge_width, badge_height); - Padding = new MarginPadding(5); - - Child = fadeContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - text = new FillFlowContainer - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new[] - { - new OsuSpriteText - { - Text = stream.DisplayName, - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 12), - Margin = new MarginPadding { Top = 6 }, - }, - new OsuSpriteText - { - Text = stream.LatestBuild.DisplayVersion, - Font = OsuFont.GetFont(weight: FontWeight.Light, size: 16), - }, - new OsuSpriteText - { - Text = stream.LatestBuild.Users > 0 ? $"{stream.LatestBuild.Users:N0} {"user".Pluralize(stream.LatestBuild.Users == 1)} online" : null, - Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 10), - Colour = new Color4(203, 164, 218, 255), - }, - } - }, - expandingBar = new ExpandingBar - { - Anchor = Anchor.TopCentre, - Colour = stream.Colour, - ExpandedSize = 4, - CollapsedSize = 2, - IsCollapsed = true - }, - } - }; - - SelectedTab.BindValueChanged(_ => updateState(), true); + this.stream = stream; } [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(OverlayColourProvider colourProvider) { - sampleClick = audio.Samples.Get(@"UI/generic-select-soft"); - sampleHover = audio.Samples.Get(@"UI/generic-hover-soft"); + Size = new Vector2(stream.IsFeatured ? badge_width * 2 : badge_width, 60); + Padding = new MarginPadding(5); + + AddRange(new Drawable[] + { + fadeContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + text = new FillFlowContainer + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Margin = new MarginPadding { Top = 6 }, + Children = new[] + { + new OsuSpriteText + { + Text = stream.DisplayName, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), + }, + new OsuSpriteText + { + Text = stream.LatestBuild.DisplayVersion, + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), + }, + new OsuSpriteText + { + Text = stream.LatestBuild.Users > 0 ? $"{stream.LatestBuild.Users:N0} {"user".Pluralize(stream.LatestBuild.Users == 1)} online" : null, + Font = OsuFont.GetFont(size: 10), + Colour = colourProvider.Foreground1 + }, + } + }, + expandingBar = new ExpandingBar + { + Anchor = Anchor.TopCentre, + Colour = stream.Colour, + ExpandedSize = 4, + CollapsedSize = 2, + IsCollapsed = true + }, + } + }, + new HoverClickSounds() + }); + + SelectedTab.BindValueChanged(_ => updateState(), true); } protected override void OnActivated() => updateState(); protected override void OnDeactivated() => updateState(); - protected override bool OnClick(ClickEvent e) - { - sampleClick?.Play(); - return base.OnClick(e); - } - protected override bool OnHover(HoverEvent e) { - sampleHover?.Play(); updateState(); - return base.OnHover(e); } diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs index ca57ba24e2..ccb1314885 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs +++ b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs @@ -9,33 +9,34 @@ using System.Linq; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osuTK.Graphics; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Changelog { public class UpdateStreamBadgeArea : TabControl { - public UpdateStreamBadgeArea() + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; AddInternal(new Box { - Colour = Color4.Black, - Alpha = 0.12f, RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background5, }); } public void Populate(List streams) { - foreach (APIUpdateStream updateStream in streams) + foreach (var updateStream in streams) AddItem(updateStream); } protected override bool OnHover(HoverEvent e) { - foreach (UpdateStreamBadge streamBadge in TabContainer.Children.OfType()) + foreach (var streamBadge in TabContainer.Children.OfType()) streamBadge.EnableDim(); return base.OnHover(e); @@ -43,7 +44,7 @@ namespace osu.Game.Overlays.Changelog protected override void OnHoverLost(HoverLostEvent e) { - foreach (UpdateStreamBadge streamBadge in TabContainer.Children.OfType()) + foreach (var streamBadge in TabContainer.Children.OfType()) streamBadge.DisableDim(); base.OnHoverLost(e); From 44ddc585daf94f81b7c48f916bd8e9e4ffc73cbe Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 21 Feb 2020 18:40:42 +0300 Subject: [PATCH 08/43] Remove unused usings --- osu.Game/Overlays/Changelog/ChangelogListing.cs | 1 - osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index 55c79e7e79..9b74a8da6d 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; -using osuTK.Graphics; namespace osu.Game.Overlays.Changelog { diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs index ccb1314885..639c0d9780 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs +++ b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs @@ -8,7 +8,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; -using osuTK.Graphics; using osu.Framework.Allocation; namespace osu.Game.Overlays.Changelog From 894b50f95572899305df5868236acdf8723d70ac Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 22 Feb 2020 03:24:50 +0300 Subject: [PATCH 09/43] Basic implementation of BeatmapSetCommentsContainer --- osu.Game/Overlays/BeatmapSet/Info.cs | 11 ---- osu.Game/Overlays/BeatmapSetOverlay.cs | 76 ++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 0f2d6a9e35..bac658b76e 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -3,17 +3,14 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { @@ -43,14 +40,6 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.X; Height = base_height; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.25f), - Type = EdgeEffectType.Shadow, - Radius = 3, - Offset = new Vector2(0f, 1f), - }; Children = new Drawable[] { diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index d29997f7e5..5b5580f286 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -4,8 +4,10 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Beatmaps; @@ -13,8 +15,10 @@ using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet.Scores; +using osu.Game.Overlays.Comments; using osu.Game.Rulesets; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays { @@ -40,6 +44,7 @@ namespace osu.Game.Overlays { OsuScrollContainer scroll; Info info; + BeatmapSetCommentsContainer comments; Children = new Drawable[] { @@ -51,28 +56,38 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, - Child = new ReverseChildIDFillFlowContainer + Child = new ReverseChildIDFillFlowContainer
{ RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 20), - Children = new Drawable[] + Children = new[] { - new ReverseChildIDFillFlowContainer + new Section { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + Child = new ReverseChildIDFillFlowContainer { - Header = new Header(), - info = new Info() + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + Header = new Header(), + info = new Info() + } + }, + }, + new Section + { + Child = new ScoresContainer + { + Beatmap = { BindTarget = Header.Picker.Beatmap } } }, - new ScoresContainer + new Section { - Beatmap = { BindTarget = Header.Picker.Beatmap } + Child = comments = new BeatmapSetCommentsContainer() } }, }, @@ -81,6 +96,7 @@ namespace osu.Game.Overlays Header.BeatmapSet.BindTo(beatmapSet); info.BeatmapSet.BindTo(beatmapSet); + comments.BeatmapSet.BindTo(beatmapSet); Header.Picker.Beatmap.ValueChanged += b => { @@ -143,5 +159,43 @@ namespace osu.Game.Overlays beatmapSet.Value = set; Show(); } + + private class Section : Container + { + public Section() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + } + } + + private class BeatmapSetCommentsContainer : CommentsContainer + { + public readonly Bindable BeatmapSet = new Bindable(); + + public BeatmapSetCommentsContainer() + { + BeatmapSet.BindValueChanged(beatmapSet => + { + if (beatmapSet.NewValue?.OnlineBeatmapSetID.HasValue != true) + { + Hide(); + } + else + { + Show(); + ShowComments(CommentableType.Beatmapset, beatmapSet.NewValue.OnlineBeatmapSetID.Value); + } + }, true); + } + } } } From 63006e8672276d44ccd85ae12a163087e6d84cb5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 22 Feb 2020 03:40:59 +0300 Subject: [PATCH 10/43] Refactor to avoid visual inconsistency for beatmaps with no leaderboard --- .../BeatmapSet/BeatmapSetLayoutSection.cs | 29 +++++++++++ .../BeatmapSet/Scores/ScoresContainer.cs | 17 +++---- osu.Game/Overlays/BeatmapSetOverlay.cs | 48 +++++-------------- 3 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs new file mode 100644 index 0000000000..e6d433f7bc --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs @@ -0,0 +1,29 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class BeatmapSetLayoutSection : Container + { + public BeatmapSetLayoutSection() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index e831c8ce42..7607eac1f8 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -19,7 +19,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoresContainer : CompositeDrawable + public class ScoresContainer : BeatmapSetLayoutSection { private const int spacing = 15; @@ -34,7 +34,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly LoadingLayer loading; private readonly LeaderboardModSelector modSelector; private readonly NoScoresPlaceholder noScoresPlaceholder; - private readonly FillFlowContainer content; private readonly NotSupporterPlaceholder notSupporterPlaceholder; [Resolved] @@ -76,15 +75,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public ScoresContainer() { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChildren = new Drawable[] + AddRange(new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - content = new FillFlowContainer + new FillFlowContainer { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -164,8 +161,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } - }, - }; + } + }); } [BackgroundDependencyLoader] @@ -223,7 +220,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (Beatmap.Value?.OnlineBeatmapID.HasValue != true || Beatmap.Value.Status <= BeatmapSetOnlineStatus.Pending) { Scores = null; - content.Hide(); + Hide(); return; } @@ -237,7 +234,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores notSupporterPlaceholder.Hide(); - content.Show(); + Show(); loading.Show(); getScoresRequest = new GetScoresRequest(Beatmap.Value, Beatmap.Value.Ruleset, scope.Value, modSelector.SelectedMods); diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 5b5580f286..efa9e27f5c 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -4,10 +4,8 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Beatmaps; @@ -18,7 +16,6 @@ using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Overlays.Comments; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays { @@ -44,7 +41,7 @@ namespace osu.Game.Overlays { OsuScrollContainer scroll; Info info; - BeatmapSetCommentsContainer comments; + CommentsSection comments; Children = new Drawable[] { @@ -56,7 +53,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, - Child = new ReverseChildIDFillFlowContainer
+ Child = new ReverseChildIDFillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -64,7 +61,7 @@ namespace osu.Game.Overlays Spacing = new Vector2(0, 20), Children = new[] { - new Section + new BeatmapSetLayoutSection { Child = new ReverseChildIDFillFlowContainer { @@ -78,17 +75,11 @@ namespace osu.Game.Overlays } }, }, - new Section + new ScoresContainer { - Child = new ScoresContainer - { - Beatmap = { BindTarget = Header.Picker.Beatmap } - } + Beatmap = { BindTarget = Header.Picker.Beatmap } }, - new Section - { - Child = comments = new BeatmapSetCommentsContainer() - } + comments = new CommentsSection() }, }, }, @@ -160,29 +151,16 @@ namespace osu.Game.Overlays Show(); } - private class Section : Container - { - public Section() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.25f), - Type = EdgeEffectType.Shadow, - Radius = 3, - Offset = new Vector2(0f, 1f), - }; - } - } - - private class BeatmapSetCommentsContainer : CommentsContainer + private class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); - public BeatmapSetCommentsContainer() + public CommentsSection() { + CommentsContainer comments; + + Add(comments = new CommentsContainer()); + BeatmapSet.BindValueChanged(beatmapSet => { if (beatmapSet.NewValue?.OnlineBeatmapSetID.HasValue != true) @@ -192,7 +170,7 @@ namespace osu.Game.Overlays else { Show(); - ShowComments(CommentableType.Beatmapset, beatmapSet.NewValue.OnlineBeatmapSetID.Value); + comments.ShowComments(CommentableType.Beatmapset, beatmapSet.NewValue.OnlineBeatmapSetID.Value); } }, true); } From c9d600b69c0320967e65aff73d8fd53d7c76cafe Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 22 Feb 2020 09:39:17 +0100 Subject: [PATCH 11/43] Show RankingsOverlay when clicking on charts button --- osu.Game/Screens/Charts/ChartInfo.cs | 9 --------- osu.Game/Screens/Charts/ChartListing.cs | 16 ---------------- osu.Game/Screens/Menu/MainMenu.cs | 5 ++--- 3 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 osu.Game/Screens/Charts/ChartInfo.cs delete mode 100644 osu.Game/Screens/Charts/ChartListing.cs diff --git a/osu.Game/Screens/Charts/ChartInfo.cs b/osu.Game/Screens/Charts/ChartInfo.cs deleted file mode 100644 index d9a9ad5eeb..0000000000 --- a/osu.Game/Screens/Charts/ChartInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Screens.Charts -{ - public class ChartInfo : ScreenWhiteBox - { - } -} diff --git a/osu.Game/Screens/Charts/ChartListing.cs b/osu.Game/Screens/Charts/ChartListing.cs deleted file mode 100644 index 18bba6433f..0000000000 --- a/osu.Game/Screens/Charts/ChartListing.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; - -namespace osu.Game.Screens.Charts -{ - public class ChartListing : ScreenWhiteBox - { - protected override IEnumerable PossibleChildren => new[] - { - typeof(ChartInfo) - }; - } -} diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index c70fbb67a4..af5db4ce8c 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -18,7 +18,6 @@ using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Overlays.Dialog; using osu.Game.Screens.Backgrounds; -using osu.Game.Screens.Charts; using osu.Game.Screens.Edit; using osu.Game.Screens.Multi; using osu.Game.Screens.Select; @@ -73,7 +72,7 @@ namespace osu.Game.Screens.Menu private SongTicker songTicker; [BackgroundDependencyLoader(true)] - private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics) + private void load(DirectOverlay direct, SettingsOverlay settings, RankingsOverlay rankings, OsuConfigManager config, SessionStatics statics) { holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); @@ -101,7 +100,6 @@ namespace osu.Game.Screens.Menu { buttons = new ButtonSystem { - OnChart = delegate { this.Push(new ChartListing()); }, OnEdit = delegate { this.Push(new Editor()); }, OnSolo = onSolo, OnMulti = delegate { this.Push(new Multiplayer()); }, @@ -136,6 +134,7 @@ namespace osu.Game.Screens.Menu buttons.OnSettings = () => settings?.ToggleVisibility(); buttons.OnDirect = () => direct?.ToggleVisibility(); + buttons.OnChart = () => rankings?.ToggleVisibility(); LoadComponentAsync(background = new BackgroundScreenDefault()); preloadSongSelect(); From 5aa5a1bbdd0aab61055ff5d4d9224b201e32e860 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 03:36:15 +0900 Subject: [PATCH 12/43] Reduce transform time of judgement lines (visually looks almost the same) --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 208bdd17ad..d54d4abd14 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -228,7 +228,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private class JudgementLine : CompositeDrawable { - private const int judgement_fade_duration = 10000; + private const int judgement_fade_duration = 5000; public JudgementLine() { @@ -255,7 +255,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Width = 0; this.ResizeWidthTo(1, 200, Easing.OutElasticHalf); - this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); + this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration).Expire(); } } } From 3daa49f1bd2eb6be3881995c337cb3c8a57fc22e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 03:39:12 +0900 Subject: [PATCH 13/43] Clean up old judgement lines if too many are already present --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d54d4abd14..48c74886a1 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -207,11 +207,16 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private double floatingAverage; private Container colourBars; + private const int max_concurrent_judgements = 50; + public override void OnNewJudgement(JudgementResult judgement) { if (!judgement.IsHit) return; + if (judgementsContainer.Count >= max_concurrent_judgements) + judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + 100)?.FadeOut(100).Expire(); + judgementsContainer.Add(new JudgementLine { Y = getRelativeJudgementPosition(judgement.TimeOffset), From e8ebb315175c994c47e1c53f70ee2c93efd532a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 03:53:51 +0900 Subject: [PATCH 14/43] Expire old judgement lines if too many exist --- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 17 +++++++++++++++++ .../Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 8904b54b0d..5f2200b049 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Judgements; using osu.Framework.Utils; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Threading; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Mania.Scoring; @@ -43,6 +44,22 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("New max negative", () => newJudgement(-hitWindows.WindowFor(HitResult.Meh)), 20); AddRepeatStep("New max positive", () => newJudgement(hitWindows.WindowFor(HitResult.Meh)), 20); AddStep("New fixed judgement (50ms)", () => newJudgement(50)); + + AddStep("Judgement barrage", () => + { + int runCount = 0; + + ScheduledDelegate del = null; + + del = Scheduler.AddDelayed(() => + { + newJudgement(runCount++ / 10f); + + if (runCount == 500) + // ReSharper disable once AccessToModifiedClosure + del?.Cancel(); + }, 10, true); + }); } [Test] diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 48c74886a1..c297ddc981 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -215,7 +215,17 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters return; if (judgementsContainer.Count >= max_concurrent_judgements) - judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + 100)?.FadeOut(100).Expire(); + { + const double quick_fade_time = 100; + + var old = judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + quick_fade_time); + + if (old != null) + { + old.ClearTransforms(); + old.FadeOut(quick_fade_time).Expire(); + } + } judgementsContainer.Add(new JudgementLine { From cb9a7ee0bb9366caf92e4994825d9554d73a8862 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 04:05:37 +0900 Subject: [PATCH 15/43] Give FollowPointConnections a valid lifetime --- .../Connections/FollowPointConnection.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index a5e89210f6..7165697022 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections private const int spacing = 32; private const double preempt = 800; + public override bool RemoveWhenNotAlive => false; + /// /// The start time of . /// @@ -79,27 +81,31 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections drawableObject.HitObject.DefaultsApplied += scheduleRefresh; } - private void scheduleRefresh() => Scheduler.AddOnce(refresh); + private void scheduleRefresh() + { + Scheduler.AddOnce(refresh); + } private void refresh() { ClearInternal(); - if (End == null) - return; - OsuHitObject osuStart = Start.HitObject; - OsuHitObject osuEnd = End.HitObject; + double startTime = osuStart.GetEndTime(); - if (osuEnd.NewCombo) - return; + LifetimeStart = startTime; - if (osuStart is Spinner || osuEnd is Spinner) + OsuHitObject osuEnd = End?.HitObject; + + if (osuEnd == null || osuEnd.NewCombo || osuStart is Spinner || osuEnd is Spinner) + { + // ensure we always set a lifetime for full LifetimeManagementContainer benefits + LifetimeEnd = LifetimeStart; return; + } Vector2 startPosition = osuStart.EndPosition; Vector2 endPosition = osuEnd.Position; - double startTime = osuStart.GetEndTime(); double endTime = osuEnd.StartTime; Vector2 distanceVector = endPosition - startPosition; @@ -107,6 +113,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections float rotation = (float)(Math.Atan2(distanceVector.Y, distanceVector.X) * (180 / Math.PI)); double duration = endTime - startTime; + double finalTransformEndTime = startTime; + for (int d = (int)(spacing * 1.5); d < distance - spacing; d += spacing) { float fraction = (float)d / distance; @@ -131,10 +139,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections fp.ScaleTo(osuEnd.Scale, osuEnd.TimeFadeIn, Easing.Out); fp.MoveTo(pointEndPosition, osuEnd.TimeFadeIn, Easing.Out); fp.Delay(fadeOutTime - fadeInTime).FadeOut(osuEnd.TimeFadeIn); - } - fp.Expire(true); + finalTransformEndTime = fadeOutTime + osuEnd.TimeFadeIn; + } } + + LifetimeStart = startTime; + LifetimeEnd = finalTransformEndTime; } } } From 090d9d93506a8a8e658b1e0bd990f6f9107eebc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 04:37:04 +0900 Subject: [PATCH 16/43] Make FollowPointRenderer a LifetimeManagementContainer --- .../Objects/Drawables/Connections/FollowPointRenderer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs index be192080f9..4d73e711bb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// Visualises connections between s. /// - public class FollowPointRenderer : CompositeDrawable + public class FollowPointRenderer : LifetimeManagementContainer { /// /// All the s contained by this . @@ -45,8 +45,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// The index of in . private void addConnection(FollowPointConnection connection) { - AddInternal(connection); - // Groups are sorted by their start time when added such that the index can be used to post-process other surrounding connections int index = connections.AddInPlace(connection, Comparer.Create((g1, g2) => g1.StartTime.Value.CompareTo(g2.StartTime.Value))); @@ -74,6 +72,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections FollowPointConnection previousConnection = connections[index - 1]; previousConnection.End = connection.Start; } + + AddInternal(connection); } /// From 8dbcdebd287b5d1a9b73c4d6f499a481c0d47eeb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 04:58:52 +0900 Subject: [PATCH 17/43] Use LoadingLayer at player loading screen --- osu.Game/Graphics/UserInterface/LoadingLayer.cs | 2 +- osu.Game/Screens/Play/BeatmapMetadataDisplay.cs | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index 25a62acaba..35b33c3d03 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface protected override void Update() { base.Update(); - MainContents.Size = new Vector2(Math.Min(100, Math.Min(DrawWidth, DrawHeight) * 0.25f)); + MainContents.Size = new Vector2(Math.Clamp(Math.Min(DrawWidth, DrawHeight) * 0.25f, 30, 100)); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index 77ee52f23e..a84a85ea47 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -15,7 +15,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play.HUD; using osuTK; -using osuTK.Graphics; namespace osu.Game.Screens.Play { @@ -63,15 +62,9 @@ namespace osu.Game.Screens.Play set { if (value) - { loading.Show(); - backgroundSprite.FadeColour(OsuColour.Gray(0.5f), 400, Easing.OutQuint); - } else - { loading.Hide(); - backgroundSprite.FadeColour(Color4.White, 400, Easing.OutQuint); - } } } @@ -138,7 +131,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, FillMode = FillMode.Fill, }, - loading = new LoadingSpinner { Scale = new Vector2(1.3f) } + loading = new LoadingLayer(backgroundSprite) } }, new OsuSpriteText From aaa888a7c14b25aef453e4de785b835b73d26013 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 05:00:38 +0900 Subject: [PATCH 18/43] Adjust spin duration to make rotation more variable --- osu.Game/Graphics/UserInterface/LoadingSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingSpinner.cs b/osu.Game/Graphics/UserInterface/LoadingSpinner.cs index b5a235f9d8..36d429b8c1 100644 --- a/osu.Game/Graphics/UserInterface/LoadingSpinner.cs +++ b/osu.Game/Graphics/UserInterface/LoadingSpinner.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface private void rotate() { - spinner.Spin(spin_duration * 4, RotationDirection.Clockwise); + spinner.Spin(spin_duration * 3.5f, RotationDirection.Clockwise); MainContents.RotateTo(0).Then() .RotateTo(90, spin_duration, Easing.InOutQuart).Then() From 560cf21b12af41a100aa276f1a589263b7baed75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 05:28:59 +0900 Subject: [PATCH 19/43] Add lenience to comparison Noticed that they could still stack up on maps with hitcircles at the same point in time (centipede). --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index c297ddc981..9edbddc0b1 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -214,11 +214,12 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters if (!judgement.IsHit) return; - if (judgementsContainer.Count >= max_concurrent_judgements) + if (judgementsContainer.Count > max_concurrent_judgements) { const double quick_fade_time = 100; - var old = judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + quick_fade_time); + // check with a bit of lenience to avoid precision error in comparison. + var old = judgementsContainer.FirstOrDefault(j => j.LifetimeEnd > Clock.CurrentTime + quick_fade_time * 1.1); if (old != null) { From 74c7e29108e9bc610ccd635c133211115d7a50c7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 23 Feb 2020 01:22:37 +0300 Subject: [PATCH 20/43] Apply suggestions --- osu.Game/Overlays/Changelog/ChangelogBuild.cs | 5 +++-- osu.Game/Overlays/Changelog/UpdateStreamBadge.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index 94bb8b5abe..8aee76cb08 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Changelog Origin = Anchor.CentreRight, Size = new Vector2(10), Icon = entry.Type == ChangelogEntryType.Fix ? FontAwesome.Solid.Check : FontAwesome.Solid.Plus, - Colour = entryColour.Darken(0.7f), + Colour = entryColour.Opacity(0.5f), Margin = new MarginPadding { Right = 5 }, }, title = new LinkFlowContainer @@ -123,10 +123,11 @@ namespace osu.Game.Overlays.Changelog }); } - title.AddText(" by ", t => + title.AddText("by ", t => { t.Font = fontMedium.With(italics: true); t.Colour = entryColour; + t.Padding = new MarginPadding { Left = 10 }; }); if (entry.GithubUser.UserId != null) diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs index 99929058e2..10aca31441 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs +++ b/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Changelog }, new OsuSpriteText { - Text = stream.LatestBuild.Users > 0 ? $"{stream.LatestBuild.Users:N0} {"user".Pluralize(stream.LatestBuild.Users == 1)} online" : null, + Text = stream.LatestBuild.Users > 0 ? $"{"user".ToQuantity(stream.LatestBuild.Users, "N0")} online" : null, Font = OsuFont.GetFont(size: 10), Colour = colourProvider.Foreground1 }, From ffc7eaa3f212d50a44bf1692b6111bd007f8eb72 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 13:01:30 +0900 Subject: [PATCH 21/43] Fix hitobjects with unknown lifetimes by enforcing non-null judgement We've seen multiple cases where DrawableHitObject are stuck in the lifetime management container due to not implementing a judgement (meaning they are never "hit" or "missed"). To avoid this going forward CreateJudgement() must be implemented and return a non-null judgement. This fixes BananaShower and JuiceStreams in osu!catch. This also makes HitObject abstract and cleans up convert HitObject implementations. --- .../Objects/BananaShower.cs | 3 +++ osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 3 +++ .../TestSceneDrawableJudgement.cs | 2 +- .../Judgements/HoldNoteJudgement.cs | 14 -------------- osu.Game.Rulesets.Mania/Objects/BarLine.cs | 3 +++ osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 3 +-- .../TestSceneDrawableJudgement.cs | 2 +- .../Judgements/OsuSliderTailJudgement.cs | 14 -------------- .../Objects/SliderTailCircle.cs | 3 +-- .../TestSceneSwellJudgements.cs | 3 +-- .../TestSceneTaikoPlayfield.cs | 8 ++++---- osu.Game.Rulesets.Taiko/Objects/SwellTick.cs | 3 +-- .../TestSceneDrainingHealthProcessor.cs | 1 + .../Gameplay/TestSceneHitObjectAccentColour.cs | 2 +- .../Gameplay/TestSceneHitObjectContainer.cs | 12 ++++++------ .../TestSceneDrawableScrollingRuleset.cs | 4 ++-- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 2 +- .../Gameplay/TestSceneScrollingHitObjects.cs | 4 ++-- .../Visual/Gameplay/TestSceneSongProgress.cs | 4 ++-- .../SongSelect/TestSceneBeatmapInfoWedge.cs | 2 +- .../Rulesets/Judgements/IgnoreJudgement.cs | 6 +++--- osu.Game/Rulesets/Objects/ConvertHitObject.cs | 18 ++++++++++++++++++ osu.Game/Rulesets/Objects/HitObject.cs | 11 ++++++----- .../Objects/Legacy/Catch/ConvertHit.cs | 2 +- .../Objects/Legacy/Catch/ConvertSpinner.cs | 2 +- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Objects/Legacy/Mania/ConvertHit.cs | 5 +---- .../Objects/Legacy/Mania/ConvertHold.cs | 5 +---- .../Objects/Legacy/Mania/ConvertSlider.cs | 3 --- .../Objects/Legacy/Mania/ConvertSpinner.cs | 5 +---- .../Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 5 +---- .../Objects/Legacy/Osu/ConvertSlider.cs | 3 --- .../Objects/Legacy/Osu/ConvertSpinner.cs | 5 +---- .../Objects/Legacy/Taiko/ConvertHit.cs | 5 +---- .../Objects/Legacy/Taiko/ConvertSlider.cs | 3 --- .../Objects/Legacy/Taiko/ConvertSpinner.cs | 5 +---- 36 files changed, 72 insertions(+), 105 deletions(-) delete mode 100644 osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs delete mode 100644 osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs rename osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs => osu.Game/Rulesets/Judgements/IgnoreJudgement.cs (63%) create mode 100644 osu.Game/Rulesets/Objects/ConvertHitObject.cs diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index 0c754412e5..c3488aec11 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Catch.Objects @@ -11,6 +12,8 @@ namespace osu.Game.Rulesets.Catch.Objects public override bool LastInCombo => true; + public override Judgement CreateJudgement() => new IgnoreJudgement(); + protected override void CreateNestedHitObjects() { base.CreateNestedHitObjects(); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 11e2466275..642ff0246e 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -7,6 +7,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -19,6 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects /// private const float base_scoring_distance = 100; + public override Judgement CreateJudgement() => new IgnoreJudgement(); + public int RepeatCount { get; set; } public double Velocity; diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs index 692d079c16..7b71f2feda 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Tests foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) { AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableManiaJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null) + new DrawableManiaJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs deleted file mode 100644 index e8b48768a1..0000000000 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Rulesets.Mania.Judgements -{ - public class HoldNoteJudgement : ManiaJudgement - { - public override bool AffectsCombo => false; - - protected override int NumericResultFor(HitResult result) => 0; - } -} diff --git a/osu.Game.Rulesets.Mania/Objects/BarLine.cs b/osu.Game.Rulesets.Mania/Objects/BarLine.cs index 0981b028b2..09a746042b 100644 --- a/osu.Game.Rulesets.Mania/Objects/BarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/BarLine.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mania.Objects @@ -8,5 +9,7 @@ namespace osu.Game.Rulesets.Mania.Objects public class BarLine : ManiaHitObject, IBarLine { public bool Major { get; set; } + + public override Judgement CreateJudgement() => new IgnoreJudgement(); } } diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 86d3d2b2b0..049bf55f90 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -4,7 +4,6 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; @@ -103,7 +102,7 @@ namespace osu.Game.Rulesets.Mania.Objects } } - public override Judgement CreateJudgement() => new HoldNoteJudgement(); + public override Judgement CreateJudgement() => new IgnoreJudgement(); protected override HitWindows CreateHitWindows() => HitWindows.Empty; } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index 02d4406809..8f72e2f60d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) { AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableOsuJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null) + new DrawableOsuJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs deleted file mode 100644 index 5104d9494b..0000000000 --- a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Rulesets.Osu.Judgements -{ - public class OsuSliderTailJudgement : OsuJudgement - { - public override bool AffectsCombo => false; - - protected override int NumericResultFor(HitResult result) => 0; - } -} diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs index c17d2275b8..127c36fcc0 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs @@ -4,7 +4,6 @@ using osu.Framework.Bindables; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects @@ -23,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects pathVersion.BindValueChanged(_ => Position = slider.EndPosition); } - public override Judgement CreateJudgement() => new OsuSliderTailJudgement(); + public override Judgement CreateJudgement() => new IgnoreJudgement(); protected override HitWindows CreateHitWindows() => HitWindows.Empty; } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs index f27e329e8e..ccacc50de1 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Screens.Play; using osu.Game.Tests.Visual; @@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Tests public void TestZeroTickTimeOffsets() { AddUntilStep("gameplay finished", () => Player.ScoreProcessor.HasCompleted); - AddAssert("all tick offsets are 0", () => Player.Results.Where(r => r.Judgement is TaikoSwellTickJudgement).All(r => r.TimeOffset == 0)); + AddAssert("all tick offsets are 0", () => Player.Results.Where(r => r.HitObject is SwellTick).All(r => r.TimeOffset == 0)); } protected override bool Autoplay => true; diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index c01eef5252..c8c4d004d6 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult }); } private void addStrongHitJudgement(bool kiai) @@ -163,13 +163,13 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new HitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new ConvertHitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great }); } private void addMissJudgement() { - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = HitResult.Miss }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs index 91f4d3dbe7..bdc0478195 100644 --- a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs @@ -3,13 +3,12 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects { public class SwellTick : TaikoHitObject { - public override Judgement CreateJudgement() => new TaikoSwellTickJudgement(); + public override Judgement CreateJudgement() => new IgnoreJudgement(); protected override HitWindows CreateHitWindows() => HitWindows.Empty; } diff --git a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs index 244e37f017..885abb61b5 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs @@ -154,6 +154,7 @@ namespace osu.Game.Tests.Gameplay private class JudgeableHitObject : HitObject { public override Judgement CreateJudgement() => new Judgement(); + protected override HitWindows CreateHitWindows() => new HitWindows(); } } } diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 17dc27543d..e99a10524e 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Gameplay } } - private class TestHitObjectWithCombo : HitObject, IHasComboInformation + private class TestHitObjectWithCombo : ConvertHitObject, IHasComboInformation { public bool NewCombo { get; } = false; public int ComboOffset { get; } = 0; diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs index f2bfccb6de..6452857bad 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs @@ -27,9 +27,9 @@ namespace osu.Game.Tests.Gameplay { DrawableHitObject hitObject = null; - AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 }))); + AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 }))); - AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 }))); + AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 }))); AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 0); } @@ -39,9 +39,9 @@ namespace osu.Game.Tests.Gameplay { DrawableHitObject hitObject = null; - AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 }))); + AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 }))); - AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject()))); + AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject()))); AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 1); } @@ -54,8 +54,8 @@ namespace osu.Game.Tests.Gameplay AddStep("setup", () => { - container.Add(firstObject = new TestDrawableHitObject(new HitObject())); - container.Add(secondObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 })); + container.Add(firstObject = new TestDrawableHitObject(new ConvertHitObject())); + container.Add(secondObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 })); }); AddStep("move first object after second", () => firstObject.HitObject.StartTime = 2000); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 46f62b9541..d350c3d58d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -163,7 +163,7 @@ namespace osu.Game.Tests.Visual.Gameplay var beatmap = new Beatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo } }; for (int i = 0; i < 10; i++) - beatmap.HitObjects.Add(new HitObject { StartTime = i * time_range }); + beatmap.HitObjects.Add(new ConvertHitObject { StartTime = i * time_range }); return beatmap; } @@ -289,7 +289,7 @@ namespace osu.Game.Tests.Visual.Gameplay #region HitObject - private class TestHitObject : HitObject, IHasEndTime + private class TestHitObject : ConvertHitObject, IHasEndTime { public double EndTime { get; set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 8904b54b0d..494611d414 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(double offset = 0) { - var judgement = new JudgementResult(new HitObject(), new Judgement()) + var judgement = new JudgementResult(new ConvertHitObject(), new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index d03716db2e..c2a71eadae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestDrawableControlPoint : DrawableHitObject { public TestDrawableControlPoint(ScrollingDirection direction, double time) - : base(new HitObject { StartTime = time }) + : base(new ConvertHitObject { StartTime = time }) { Origin = Anchor.Centre; @@ -255,7 +255,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestDrawableHitObject : DrawableHitObject { public TestDrawableHitObject(double time) - : base(new HitObject { StartTime = time }) + : base(new ConvertHitObject { StartTime = time }) { Origin = Anchor.Custom; OriginPosition = new Vector2(75 / 4.0f); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index b9b13d7bd8..6a60ae110b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var objects = new List(); for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000) - objects.Add(new HitObject { StartTime = i }); + objects.Add(new ConvertHitObject { StartTime = i }); replaceObjects(objects); } @@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var objects = new List(); for (double i = 0; i < 5000; i++) - objects.Add(new HitObject { StartTime = i }); + objects.Add(new ConvertHitObject { StartTime = i }); replaceObjects(objects); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index f49d7a14a6..5cac897200 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -194,7 +194,7 @@ namespace osu.Game.Tests.Visual.SongSelect public new BufferedWedgeInfo Info => base.Info; } - private class TestHitObject : HitObject, IHasPosition + private class TestHitObject : ConvertHitObject, IHasPosition { public float X { get; } = 0; public float Y { get; } = 0; diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs b/osu.Game/Rulesets/Judgements/IgnoreJudgement.cs similarity index 63% rename from osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs rename to osu.Game/Rulesets/Judgements/IgnoreJudgement.cs index b28b6a0d17..1871249c94 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs +++ b/osu.Game/Rulesets/Judgements/IgnoreJudgement.cs @@ -1,11 +1,11 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Taiko.Judgements +namespace osu.Game.Rulesets.Judgements { - public class TaikoSwellTickJudgement : TaikoJudgement + public class IgnoreJudgement : Judgement { public override bool AffectsCombo => false; diff --git a/osu.Game/Rulesets/Objects/ConvertHitObject.cs b/osu.Game/Rulesets/Objects/ConvertHitObject.cs new file mode 100644 index 0000000000..81a88615a3 --- /dev/null +++ b/osu.Game/Rulesets/Objects/ConvertHitObject.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Objects +{ + /// + /// A hit object only used for conversion, not actual gameplay. + /// + public class ConvertHitObject : HitObject + { + public override Judgement CreateJudgement() => new IgnoreJudgement(); + + protected override HitWindows CreateHitWindows() => HitWindows.Empty; + } +} diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index c09844e0c6..bef48f0ced 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects /// HitObjects may contain more properties for which you should be checking through the IHas* types. /// /// - public class HitObject + public abstract class HitObject { /// /// A small adjustment to the start time of control points to account for rounding/precision errors. @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Objects [JsonIgnore] public IReadOnlyList NestedHitObjects => nestedHitObjects; - public HitObject() + protected HitObject() { StartTimeBindable.ValueChanged += time => { @@ -144,9 +144,10 @@ namespace osu.Game.Rulesets.Objects /// /// Creates the that represents the scoring information for this . - /// May be null. + /// Used to decide on drawable object lifetimes. /// - public virtual Judgement CreateJudgement() => null; + [NotNull] + public abstract Judgement CreateJudgement(); /// /// Creates the for this . @@ -156,7 +157,7 @@ namespace osu.Game.Rulesets.Objects /// /// [NotNull] - protected virtual HitWindows CreateHitWindows() => new HitWindows(); + protected abstract HitWindows CreateHitWindows(); } public static class HitObjectExtensions diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHit.cs index febfd3696c..19722fb796 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHit.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch /// /// Legacy osu!catch Hit-type, used for parsing Beatmaps. /// - internal sealed class ConvertHit : HitObject, IHasCombo, IHasXPosition + internal sealed class ConvertHit : ConvertHitObject, IHasCombo, IHasXPosition { public float X { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSpinner.cs index 0089d1eb88..9de311c9d7 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSpinner.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch /// /// Legacy osu!catch Spinner-type, used for parsing Beatmaps. /// - internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasXPosition, IHasCombo + internal sealed class ConvertSpinner : ConvertHitObject, IHasEndTime, IHasXPosition, IHasCombo { public double EndTime { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 53cdf457c4..924182b265 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Objects.Legacy { - internal abstract class ConvertSlider : HitObject, IHasCurve, IHasLegacyLastTickOffset + internal abstract class ConvertSlider : ConvertHitObject, IHasCurve, IHasLegacyLastTickOffset { /// /// Scoring distance with a speed-adjusted beat length of 1 second. diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs index 883ef55df0..0b69817c13 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs @@ -2,17 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Mania { /// /// Legacy osu!mania Hit-type, used for parsing Beatmaps. /// - internal sealed class ConvertHit : HitObject, IHasXPosition + internal sealed class ConvertHit : ConvertHitObject, IHasXPosition { public float X { get; set; } - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs index 69e6f8379d..1d92d638dd 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs @@ -2,18 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Mania { - internal sealed class ConvertHold : HitObject, IHasXPosition, IHasEndTime + internal sealed class ConvertHold : ConvertHitObject, IHasXPosition, IHasEndTime { public float X { get; set; } public double EndTime { get; set; } public double Duration => EndTime - StartTime; - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs index 4486c5d906..84cde5fa95 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Mania { @@ -12,7 +11,5 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasXPosition { public float X { get; set; } - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs index c6d1f1922c..7dc13e27cd 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs @@ -2,21 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Mania { /// /// Legacy osu!mania Spinner-type, used for parsing Beatmaps. /// - internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasXPosition + internal sealed class ConvertSpinner : ConvertHitObject, IHasEndTime, IHasXPosition { public double EndTime { get; set; } public double Duration => EndTime - StartTime; public float X { get; set; } - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index e40b5b4505..069366bad3 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Rulesets.Objects.Legacy.Osu @@ -10,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Hit-type, used for parsing Beatmaps. /// - internal sealed class ConvertHit : HitObject, IHasPosition, IHasCombo + internal sealed class ConvertHit : ConvertHitObject, IHasPosition, IHasCombo { public Vector2 Position { get; set; } @@ -21,7 +20,5 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } public int ComboOffset { get; set; } - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index a163329d47..e947690668 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Rulesets.Objects.Legacy.Osu @@ -21,7 +20,5 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } public int ComboOffset { get; set; } - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index 5d96a61633..8b21aab411 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Rulesets.Objects.Legacy.Osu @@ -10,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Spinner-type, used for parsing Beatmaps. /// - internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition, IHasCombo + internal sealed class ConvertSpinner : ConvertHitObject, IHasEndTime, IHasPosition, IHasCombo { public double EndTime { get; set; } @@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float Y => Position.Y; - protected override HitWindows CreateHitWindows() => HitWindows.Empty; - public bool NewCombo { get; set; } public int ComboOffset { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs index efb9810927..cb5178ce48 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs @@ -1,15 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Rulesets.Scoring; - namespace osu.Game.Rulesets.Objects.Legacy.Taiko { /// /// Legacy osu!taiko Hit-type, used for parsing Beatmaps. /// - internal sealed class ConvertHit : HitObject + internal sealed class ConvertHit : ConvertHitObject { - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs index b365fd34ae..821554f7ee 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Rulesets.Scoring; - namespace osu.Game.Rulesets.Objects.Legacy.Taiko { /// @@ -10,6 +8,5 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko /// internal sealed class ConvertSlider : Legacy.ConvertSlider { - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs index 840ba51ac2..8e28487f2f 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs @@ -2,19 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Taiko { /// /// Legacy osu!taiko Spinner-type, used for parsing Beatmaps. /// - internal sealed class ConvertSpinner : HitObject, IHasEndTime + internal sealed class ConvertSpinner : ConvertHitObject, IHasEndTime { public double EndTime { get; set; } public double Duration => EndTime - StartTime; - - protected override HitWindows CreateHitWindows() => HitWindows.Empty; } } From 0e29d3c4a2173eecc9681b36d66985518dcd2cda Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 13:50:05 +0900 Subject: [PATCH 22/43] Correctly expire bar lines in osu!taiko and osu!mania --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs | 4 +--- osu.Game.Rulesets.Taiko/Objects/BarLine.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs | 2 ++ osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index 56bc797c7f..08b5b75f9c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -71,8 +71,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { } - protected override void UpdateStateTransforms(ArmedState state) - { - } + protected override void UpdateStateTransforms(ArmedState state) => this.FadeOut(150); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs index 2afbbc737c..6306195704 100644 --- a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Taiko.Objects @@ -8,5 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Objects public class BarLine : TaikoHitObject, IBarLine { public bool Major { get; set; } + + public override Judgement CreateJudgement() => new IgnoreJudgement(); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 1a5a797f28..e9caabbcc8 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -54,5 +54,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Alpha = 0.75f }); } + + protected override void UpdateStateTransforms(ArmedState state) => this.FadeOut(150); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 67fe18e8dd..d8614c9d3d 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -265,7 +265,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } } - if (state.Value != ArmedState.Idle && LifetimeEnd == double.MaxValue) + if (state.Value != ArmedState.Idle && LifetimeEnd == double.MaxValue || HitObject.HitWindows == null) Expire(); } else From 401bf1c92811158cf752aac264953324d3b2f761 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 14:30:08 +0900 Subject: [PATCH 23/43] Remove unnecessary checks on NotNull attributes --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 9 +++------ osu.Game/Rulesets/Scoring/JudgementProcessor.cs | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 67fe18e8dd..369bda3fc2 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -99,12 +99,9 @@ namespace osu.Game.Rulesets.Objects.Drawables { var judgement = HitObject.CreateJudgement(); - if (judgement != null) - { - Result = CreateResult(judgement); - if (Result == null) - throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); - } + Result = CreateResult(judgement); + if (Result == null) + throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); loadSamples(); } diff --git a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs index 3016007f98..334b95f808 100644 --- a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs +++ b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs @@ -125,8 +125,6 @@ namespace osu.Game.Rulesets.Scoring simulate(nested); var judgement = obj.CreateJudgement(); - if (judgement == null) - return; var result = CreateResult(obj, judgement); if (result == null) From 575946d92367f6d98fd198d1e3ddfa236718eca7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 23 Feb 2020 20:47:14 +0900 Subject: [PATCH 24/43] Expose save and export options in editor to non-dekstop platforms --- osu.Game/Screens/Edit/Editor.cs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3bec4b8f6f..d84151f5af 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -20,8 +20,6 @@ using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; using osu.Game.Screens.Edit.Design; using osuTK.Input; -using System.Collections.Generic; -using osu.Framework; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; @@ -93,17 +91,6 @@ namespace osu.Game.Screens.Edit EditorMenuBar menuBar; - var fileMenuItems = new List(); - - if (RuntimeInfo.IsDesktop) - { - fileMenuItems.Add(new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap)); - fileMenuItems.Add(new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap)); - fileMenuItems.Add(new EditorMenuItemSpacer()); - } - - fileMenuItems.Add(new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit)); - AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, @@ -134,7 +121,13 @@ namespace osu.Game.Screens.Edit { new MenuItem("File") { - Items = fileMenuItems + Items = new[] + { + new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap), + new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap), + new EditorMenuItemSpacer(), + new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit), + } } } } From 71c34a36edd568f4140f71d21788df9fe4197905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 23 Feb 2020 14:46:42 +0100 Subject: [PATCH 25/43] Use pattern matching instead of .(Has)?Value --- osu.Game/Overlays/BeatmapSetOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index efa9e27f5c..0d16c4842d 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -163,14 +163,14 @@ namespace osu.Game.Overlays BeatmapSet.BindValueChanged(beatmapSet => { - if (beatmapSet.NewValue?.OnlineBeatmapSetID.HasValue != true) + if (beatmapSet.NewValue?.OnlineBeatmapSetID is int onlineBeatmapSetID) { - Hide(); + Show(); + comments.ShowComments(CommentableType.Beatmapset, onlineBeatmapSetID); } else { - Show(); - comments.ShowComments(CommentableType.Beatmapset, beatmapSet.NewValue.OnlineBeatmapSetID.Value); + Hide(); } }, true); } From 0cfe1ac823e2e9414637405e97024f5cbd57f2ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 05:47:21 +0300 Subject: [PATCH 26/43] Implement UserSortTabControl component --- .../TestSceneUserSortTabControl.cs | 41 +++++++++++++++++++ osu.Game/Overlays/Comments/CommentsHeader.cs | 3 ++ .../Home/Friends/UserSortTabControl.cs | 19 +++++++++ osu.Game/Overlays/OverlaySortTabControl.cs | 4 +- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs create mode 100644 osu.Game/Overlays/Home/Friends/UserSortTabControl.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs new file mode 100644 index 0000000000..de7a78d355 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; +using osu.Game.Overlays.Home.Friends; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneUserSortTabControl : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(UserSortTabControl), + typeof(OverlaySortTabControl<>), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + public TestSceneUserSortTabControl() + { + UserSortTabControl control; + OsuSpriteText current; + + Add(control = new UserSortTabControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + Add(current = new OsuSpriteText()); + + control.Current.BindValueChanged(criteria => current.Text = $"Criteria: {criteria.NewValue}", true); + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 1aa40201f1..ff5602e289 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -11,6 +11,8 @@ using osu.Framework.Graphics.Sprites; using osuTK; using osu.Framework.Input.Events; using osu.Game.Graphics.Sprites; +using System.ComponentModel; +using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Overlays.Comments { @@ -109,6 +111,7 @@ namespace osu.Game.Overlays.Comments public enum CommentsSortCriteria { + [Description(@"Recent")] New, Old, Top diff --git a/osu.Game/Overlays/Home/Friends/UserSortTabControl.cs b/osu.Game/Overlays/Home/Friends/UserSortTabControl.cs new file mode 100644 index 0000000000..2479fa4638 --- /dev/null +++ b/osu.Game/Overlays/Home/Friends/UserSortTabControl.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.ComponentModel; + +namespace osu.Game.Overlays.Home.Friends +{ + public class UserSortTabControl : OverlaySortTabControl + { + } + + public enum UserSortCriteria + { + [Description(@"Recently Active")] + LastVisit, + Rank, + Username + } +} diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs index 5a713ab08e..395f3aec4c 100644 --- a/osu.Game/Overlays/OverlaySortTabControl.cs +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -15,6 +15,8 @@ using osu.Game.Graphics.Sprites; using osuTK.Graphics; using osu.Game.Overlays.Comments; using JetBrains.Annotations; +using System; +using osu.Framework.Extensions; namespace osu.Game.Overlays { @@ -132,7 +134,7 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 12), - Text = value.ToString() + Text = (value as Enum)?.GetDescription() ?? value.ToString() } } }); From b0b52146eafd10c442c6809d1f4d9f6cb0e1ee56 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 05:53:33 +0300 Subject: [PATCH 27/43] Fix crash when clicking on ShowMore button --- osu.Game/Overlays/Comments/CommentsPage.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 4f82ee5a19..591400f741 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -96,12 +96,17 @@ namespace osu.Game.Overlays.Comments { var orphaned = new List(); + // Exclude possible duplicated comments. foreach (var topLevel in bundle.Comments) + { + if (commentDictionary.ContainsKey(topLevel.Id)) + continue; + addNewComment(topLevel); + } foreach (var child in bundle.IncludedComments) { - // Included comments can contain the parent comment, which already exists in the hierarchy. if (commentDictionary.ContainsKey(child.Id)) continue; From e6cfafffe9966aee9fc9cb68b4b6d8a373c143fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Feb 2020 12:24:15 +0900 Subject: [PATCH 28/43] Fix incorrect LifetimeStart and add todo regarding Expire usage --- .../Objects/Drawables/Connections/FollowPointConnection.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index 7165697022..921b23cb13 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -113,6 +113,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections float rotation = (float)(Math.Atan2(distanceVector.Y, distanceVector.X) * (180 / Math.PI)); double duration = endTime - startTime; + double? firstTransformStartTime = null; double finalTransformEndTime = startTime; for (int d = (int)(spacing * 1.5); d < distance - spacing; d += spacing) @@ -133,6 +134,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections Scale = new Vector2(1.5f * osuEnd.Scale), }); + if (firstTransformStartTime == null) + firstTransformStartTime = fadeInTime; + using (fp.BeginAbsoluteSequence(fadeInTime)) { fp.FadeIn(osuEnd.TimeFadeIn); @@ -144,7 +148,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections } } - LifetimeStart = startTime; + // todo: use Expire() on FollowPoints and take lifetime from them when https://github.com/ppy/osu-framework/issues/3300 is fixed. + LifetimeStart = firstTransformStartTime ?? startTime; LifetimeEnd = finalTransformEndTime; } } From 7bc9a9b3d8b9e00b7fa09e7710c47fe42ea01d46 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 07:28:33 +0300 Subject: [PATCH 29/43] Implement OverlayPanelDisplayStyleControl and UserListToolbar components --- .../UserInterface/TestSceneUserListToolbar.cs | 57 +++++++++++ .../TestSceneUserSortTabControl.cs | 41 -------- .../Overlays/Home/Friends/UserListToolbar.cs | 45 +++++++++ .../OverlayPanelDisplayStyleControl.cs | 97 +++++++++++++++++++ 4 files changed, 199 insertions(+), 41 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs delete mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs create mode 100644 osu.Game/Overlays/Home/Friends/UserListToolbar.cs create mode 100644 osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs new file mode 100644 index 0000000000..02b8839922 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs @@ -0,0 +1,57 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; +using osu.Game.Overlays.Home.Friends; +using osuTK; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneUserListToolbar : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(UserSortTabControl), + typeof(OverlaySortTabControl<>), + typeof(OverlayPanelDisplayStyleControl), + typeof(UserListToolbar), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + public TestSceneUserListToolbar() + { + UserListToolbar toolbar; + OsuSpriteText sort; + OsuSpriteText displayStyle; + + Add(toolbar = new UserListToolbar + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + sort = new OsuSpriteText(), + displayStyle = new OsuSpriteText() + } + }); + + toolbar.SortCriteria.BindValueChanged(criteria => sort.Text = $"Criteria: {criteria.NewValue}", true); + toolbar.DisplayStyle.BindValueChanged(style => displayStyle.Text = $"Style: {style.NewValue}", true); + } + } +} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs deleted file mode 100644 index de7a78d355..0000000000 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUserSortTabControl.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Overlays; -using osu.Game.Overlays.Home.Friends; - -namespace osu.Game.Tests.Visual.UserInterface -{ - public class TestSceneUserSortTabControl : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(UserSortTabControl), - typeof(OverlaySortTabControl<>), - }; - - [Cached] - private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); - - public TestSceneUserSortTabControl() - { - UserSortTabControl control; - OsuSpriteText current; - - Add(control = new UserSortTabControl - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - Add(current = new OsuSpriteText()); - - control.Current.BindValueChanged(criteria => current.Text = $"Criteria: {criteria.NewValue}", true); - } - } -} diff --git a/osu.Game/Overlays/Home/Friends/UserListToolbar.cs b/osu.Game/Overlays/Home/Friends/UserListToolbar.cs new file mode 100644 index 0000000000..f7c5e9f4fd --- /dev/null +++ b/osu.Game/Overlays/Home/Friends/UserListToolbar.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osuTK; +using osu.Framework.Bindables; + +namespace osu.Game.Overlays.Home.Friends +{ + public class UserListToolbar : CompositeDrawable + { + public Bindable SortCriteria => sortControl.Current; + + public Bindable DisplayStyle => styleControl.Current; + + private readonly UserSortTabControl sortControl; + private readonly OverlayPanelDisplayStyleControl styleControl; + + public UserListToolbar() + { + AutoSizeAxes = Axes.Both; + + AddInternal(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + sortControl = new UserSortTabControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + styleControl = new OverlayPanelDisplayStyleControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + }); + } + } +} diff --git a/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs new file mode 100644 index 0000000000..952b277cac --- /dev/null +++ b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs @@ -0,0 +1,97 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osuTK; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Allocation; +using osuTK.Graphics; +using osu.Framework.Graphics.Cursor; + +namespace osu.Game.Overlays +{ + public class OverlayPanelDisplayStyleControl : OsuTabControl + { + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(OverlayPanelDisplayStyle value) => new PanelDisplayTabItem(value); + + protected override bool AddEnumEntriesAutomatically => false; + + public OverlayPanelDisplayStyleControl() + { + AutoSizeAxes = Axes.Both; + + AddTabItem(new PanelDisplayTabItem(OverlayPanelDisplayStyle.Card) + { + Icon = FontAwesome.Solid.Square + }); + AddTabItem(new PanelDisplayTabItem(OverlayPanelDisplayStyle.List) + { + Icon = FontAwesome.Solid.Bars + }); + } + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal + }; + + private class PanelDisplayTabItem : TabItem, IHasTooltip + { + public IconUsage Icon + { + set => icon.Icon = value; + } + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + public string TooltipText => $@"{Value} view"; + + private readonly SpriteIcon icon; + + public PanelDisplayTabItem(OverlayPanelDisplayStyle value) + : base(value) + { + Size = new Vector2(11); + Add(icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + }); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + protected override bool OnHover(HoverEvent e) + { + updateState(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateState(); + base.OnHoverLost(e); + } + + private void updateState() => icon.Colour = Active.Value || IsHovered ? colourProvider.Light1 : Color4.White; + } + } + + public enum OverlayPanelDisplayStyle + { + Card, + List + } +} From fe1f2858c19e8e5bf7726abe121b61c8fc9d13ca Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 23:10:37 +0300 Subject: [PATCH 30/43] Refactor to avoid duplicated code --- osu.Game/Overlays/Comments/CommentsPage.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 591400f741..1fb6032924 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -97,20 +97,12 @@ namespace osu.Game.Overlays.Comments var orphaned = new List(); // Exclude possible duplicated comments. - foreach (var topLevel in bundle.Comments) + foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments)) { - if (commentDictionary.ContainsKey(topLevel.Id)) + if (commentDictionary.ContainsKey(comment.Id)) continue; - addNewComment(topLevel); - } - - foreach (var child in bundle.IncludedComments) - { - if (commentDictionary.ContainsKey(child.Id)) - continue; - - addNewComment(child); + addNewComment(comment); } // Comments whose parents were seen later than themselves can now be added. From 4cbb2a2f591f07f6a748aa57434bf78554a9c4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 24 Feb 2020 21:30:27 +0100 Subject: [PATCH 31/43] Move comment to more pertinent place --- osu.Game/Overlays/Comments/CommentsPage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 1fb6032924..f3a774908c 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -96,9 +96,9 @@ namespace osu.Game.Overlays.Comments { var orphaned = new List(); - // Exclude possible duplicated comments. foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments)) { + // Exclude possible duplicated comments. if (commentDictionary.ContainsKey(comment.Id)) continue; From a020566b1e69c0aca51d3a30df5fa191b760d607 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 23:37:46 +0300 Subject: [PATCH 32/43] Add HoverClickSounds --- .../Overlays/OverlayPanelDisplayStyleControl.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs index 952b277cac..7269007b41 100644 --- a/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs +++ b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs @@ -60,12 +60,16 @@ namespace osu.Game.Overlays : base(value) { Size = new Vector2(11); - Add(icon = new SpriteIcon + AddRange(new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + }, + new HoverClickSounds() }); } From d8413c558bac3aa767ed51f3e1b60be446219374 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 24 Feb 2020 23:41:34 +0300 Subject: [PATCH 33/43] Use fully qualified name for enum item description in CommentsHeader --- osu.Game/Overlays/Comments/CommentsHeader.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index ff5602e289..83f44ccd80 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -11,8 +11,6 @@ using osu.Framework.Graphics.Sprites; using osuTK; using osu.Framework.Input.Events; using osu.Game.Graphics.Sprites; -using System.ComponentModel; -using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Overlays.Comments { @@ -111,7 +109,7 @@ namespace osu.Game.Overlays.Comments public enum CommentsSortCriteria { - [Description(@"Recent")] + [System.ComponentModel.Description(@"Recent")] New, Old, Top From c1455be85592c3ccf8c0ab95b27c23830927ca53 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 25 Feb 2020 10:29:03 +0300 Subject: [PATCH 34/43] Add tests --- .../Visual/Online/TestSceneCommentsPage.cs | 52 +++++++++++++++++-- osu.Game/Overlays/Comments/CommentsPage.cs | 16 +++--- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs index 0ed8864860..a28a0107a1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -13,6 +13,8 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osuTK; +using JetBrains.Annotations; +using NUnit.Framework; namespace osu.Game.Tests.Visual.Online { @@ -30,6 +32,8 @@ namespace osu.Game.Tests.Visual.Online private readonly BindableBool showDeleted = new BindableBool(); private readonly Container content; + private TestCommentsPage commentsPage; + public TestSceneCommentsPage() { Add(new FillFlowContainer @@ -57,15 +61,29 @@ namespace osu.Game.Tests.Visual.Online } } }); + } - AddStep("load comments", () => createPage(getCommentBundle())); - AddStep("load empty comments", () => createPage(getEmptyCommentBundle())); + [Test] + public void TestAppendDuplicatedComment() + { + AddStep("Create page", () => createPage(getCommentBundle())); + AddAssert("Dictionary length is 10", () => commentsPage?.DictionaryLength == 10); + AddStep("Append existing comment", () => commentsPage?.AppendComments(getCommentSubBundle())); + AddAssert("Dictionary length is 10", () => commentsPage?.DictionaryLength == 10); + } + + [Test] + public void TestEmptyBundle() + { + AddStep("Create page", () => createPage(getEmptyCommentBundle())); + AddAssert("Dictionary length is 0", () => commentsPage?.DictionaryLength == 0); } private void createPage(CommentBundle commentBundle) { + commentsPage = null; content.Clear(); - content.Add(new CommentsPage(commentBundle) + content.Add(commentsPage = new TestCommentsPage(commentBundle) { ShowDeleted = { BindTarget = showDeleted } }); @@ -182,5 +200,33 @@ namespace osu.Game.Tests.Visual.Online } }, }; + + private CommentBundle getCommentSubBundle() => new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 1, + Message = "Simple test comment", + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + VotesCount = 5 + }, + }, + IncludedComments = new List(), + }; + + private class TestCommentsPage : CommentsPage + { + public TestCommentsPage(CommentBundle commentBundle) + : base(commentBundle) + { + } + + public new void AppendComments([NotNull] CommentBundle bundle) => base.AppendComments(bundle); + + public int DictionaryLength => CommentDictionary.Count; + } } } diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index f3a774908c..9b146b0a7d 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -61,15 +61,15 @@ namespace osu.Game.Overlays.Comments return; } - appendComments(commentBundle); + AppendComments(commentBundle); } private DrawableComment getDrawableComment(Comment comment) { - if (commentDictionary.TryGetValue(comment.Id, out var existing)) + if (CommentDictionary.TryGetValue(comment.Id, out var existing)) return existing; - return commentDictionary[comment.Id] = new DrawableComment(comment) + return CommentDictionary[comment.Id] = new DrawableComment(comment) { ShowDeleted = { BindTarget = ShowDeleted }, Sort = { BindTarget = Sort }, @@ -81,25 +81,25 @@ namespace osu.Game.Overlays.Comments { var request = new GetCommentsRequest(CommentableId.Value, Type.Value, Sort.Value, page, drawableComment.Comment.Id); - request.Success += response => Schedule(() => appendComments(response)); + request.Success += response => Schedule(() => AppendComments(response)); api.PerformAsync(request); } - private readonly Dictionary commentDictionary = new Dictionary(); + protected readonly Dictionary CommentDictionary = new Dictionary(); /// /// Appends retrieved comments to the subtree rooted of comments in this page. /// /// The bundle of comments to add. - private void appendComments([NotNull] CommentBundle bundle) + protected void AppendComments([NotNull] CommentBundle bundle) { var orphaned = new List(); foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments)) { // Exclude possible duplicated comments. - if (commentDictionary.ContainsKey(comment.Id)) + if (CommentDictionary.ContainsKey(comment.Id)) continue; addNewComment(comment); @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Comments // Comments that have no parent are added as top-level comments to the flow. flow.Add(drawableComment); } - else if (commentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable)) + else if (CommentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable)) { // The comment's parent has already been seen, so the parent<-> child links can be added. comment.ParentComment = parentDrawable.Comment; From d6046abe700722023b2325ea1c6ba19664a2e8ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Feb 2020 18:59:16 +0900 Subject: [PATCH 35/43] Only expose save for now --- osu.Game/Screens/Edit/Editor.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d84151f5af..8d3b8849bc 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -20,6 +20,8 @@ using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; using osu.Game.Screens.Edit.Design; using osuTK.Input; +using System.Collections.Generic; +using osu.Framework; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; @@ -91,6 +93,16 @@ namespace osu.Game.Screens.Edit EditorMenuBar menuBar; + var fileMenuItems = new List(); + + fileMenuItems.Add(new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap)); + + if (RuntimeInfo.IsDesktop) + fileMenuItems.Add(new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap)); + + fileMenuItems.Add(new EditorMenuItemSpacer()); + fileMenuItems.Add(new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit)); + AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, @@ -121,13 +133,7 @@ namespace osu.Game.Screens.Edit { new MenuItem("File") { - Items = new[] - { - new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap), - new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap), - new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit), - } + Items = fileMenuItems } } } From a0474563545ed534f1fd6e15172be38662993705 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Feb 2020 19:07:15 +0900 Subject: [PATCH 36/43] Revert changes to make HitObject abstract --- .../TestSceneDrawableJudgement.cs | 2 +- .../TestSceneDrawableJudgement.cs | 2 +- .../TestSceneTaikoPlayfield.cs | 8 ++++---- .../Gameplay/TestSceneHitObjectAccentColour.cs | 2 +- .../Gameplay/TestSceneHitObjectContainer.cs | 12 ++++++------ .../Gameplay/TestSceneDrawableScrollingRuleset.cs | 3 ++- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 4 ++-- .../Visual/Gameplay/TestSceneScrollingHitObjects.cs | 4 ++-- .../Visual/Gameplay/TestSceneSongProgress.cs | 4 ++-- .../Visual/SongSelect/TestSceneBeatmapInfoWedge.cs | 1 + osu.Game/Rulesets/Objects/HitObject.cs | 8 ++++---- .../Objects/{ => Legacy}/ConvertHitObject.cs | 4 ++-- 12 files changed, 28 insertions(+), 26 deletions(-) rename osu.Game/Rulesets/Objects/{ => Legacy}/ConvertHitObject.cs (83%) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs index 7b71f2feda..692d079c16 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Tests foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) { AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableManiaJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null) + new DrawableManiaJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index 8f72e2f60d..02d4406809 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) { AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableOsuJudgement(new JudgementResult(new ConvertHitObject(), new Judgement()) { Type = result }, null) + new DrawableOsuJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index c8c4d004d6..c01eef5252 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); } private void addStrongHitJudgement(bool kiai) @@ -163,13 +163,13 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = hitResult }); - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new ConvertHitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new HitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great }); } private void addMissJudgement() { - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new ConvertHitObject(), new TaikoJudgement()) { Type = HitResult.Miss }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index e99a10524e..7a89642e11 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -11,8 +11,8 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Testing; using osu.Game.Audio; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; using osu.Game.Skinning; using osu.Game.Tests.Visual; diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs index 6452857bad..f2bfccb6de 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs @@ -27,9 +27,9 @@ namespace osu.Game.Tests.Gameplay { DrawableHitObject hitObject = null; - AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 }))); + AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 }))); - AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 }))); + AddStep("add late hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 }))); AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 0); } @@ -39,9 +39,9 @@ namespace osu.Game.Tests.Gameplay { DrawableHitObject hitObject = null; - AddStep("setup", () => container.Add(new TestDrawableHitObject(new ConvertHitObject { StartTime = 500 }))); + AddStep("setup", () => container.Add(new TestDrawableHitObject(new HitObject { StartTime = 500 }))); - AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new ConvertHitObject()))); + AddStep("add early hitobject", () => container.Add(hitObject = new TestDrawableHitObject(new HitObject()))); AddAssert("hitobject index is 0", () => container.IndexOf(hitObject) == 1); } @@ -54,8 +54,8 @@ namespace osu.Game.Tests.Gameplay AddStep("setup", () => { - container.Add(firstObject = new TestDrawableHitObject(new ConvertHitObject())); - container.Add(secondObject = new TestDrawableHitObject(new ConvertHitObject { StartTime = 1000 })); + container.Add(firstObject = new TestDrawableHitObject(new HitObject())); + container.Add(secondObject = new TestDrawableHitObject(new HitObject { StartTime = 1000 })); }); AddStep("move first object after second", () => firstObject.HitObject.StartTime = 2000); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index d350c3d58d..b25b81c9af 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -20,6 +20,7 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.UI; @@ -163,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay var beatmap = new Beatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo } }; for (int i = 0; i < 10; i++) - beatmap.HitObjects.Add(new ConvertHitObject { StartTime = i * time_range }); + beatmap.HitObjects.Add(new HitObject { StartTime = i * time_range }); return beatmap; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 494611d414..ddad337c66 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Game.Rulesets.Objects; using System; using System.Collections.Generic; using osu.Game.Rulesets.Judgements; @@ -12,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Mania.Scoring; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Scoring; @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(double offset = 0) { - var judgement = new JudgementResult(new ConvertHitObject(), new Judgement()) + var judgement = new JudgementResult(new HitObject(), new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index c2a71eadae..d03716db2e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestDrawableControlPoint : DrawableHitObject { public TestDrawableControlPoint(ScrollingDirection direction, double time) - : base(new ConvertHitObject { StartTime = time }) + : base(new HitObject { StartTime = time }) { Origin = Anchor.Centre; @@ -255,7 +255,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestDrawableHitObject : DrawableHitObject { public TestDrawableHitObject(double time) - : base(new ConvertHitObject { StartTime = time }) + : base(new HitObject { StartTime = time }) { Origin = Anchor.Custom; OriginPosition = new Vector2(75 / 4.0f); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 6a60ae110b..b9b13d7bd8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var objects = new List(); for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000) - objects.Add(new ConvertHitObject { StartTime = i }); + objects.Add(new HitObject { StartTime = i }); replaceObjects(objects); } @@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var objects = new List(); for (double i = 0; i < 5000; i++) - objects.Add(new ConvertHitObject { StartTime = i }); + objects.Add(new HitObject { StartTime = i }); replaceObjects(objects); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index 5cac897200..e02ebf3be1 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index bef48f0ced..477d025253 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects /// HitObjects may contain more properties for which you should be checking through the IHas* types. /// /// - public abstract class HitObject + public class HitObject { /// /// A small adjustment to the start time of control points to account for rounding/precision errors. @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Objects [JsonIgnore] public IReadOnlyList NestedHitObjects => nestedHitObjects; - protected HitObject() + public HitObject() { StartTimeBindable.ValueChanged += time => { @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Objects /// Used to decide on drawable object lifetimes. /// [NotNull] - public abstract Judgement CreateJudgement(); + public virtual Judgement CreateJudgement() => new Judgement(); /// /// Creates the for this . @@ -157,7 +157,7 @@ namespace osu.Game.Rulesets.Objects /// /// [NotNull] - protected abstract HitWindows CreateHitWindows(); + protected virtual HitWindows CreateHitWindows() => new HitWindows(); } public static class HitObjectExtensions diff --git a/osu.Game/Rulesets/Objects/ConvertHitObject.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs similarity index 83% rename from osu.Game/Rulesets/Objects/ConvertHitObject.cs rename to osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs index 81a88615a3..e3b0d8a498 100644 --- a/osu.Game/Rulesets/Objects/ConvertHitObject.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs @@ -4,12 +4,12 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Objects +namespace osu.Game.Rulesets.Objects.Legacy { /// /// A hit object only used for conversion, not actual gameplay. /// - public class ConvertHitObject : HitObject + internal abstract class ConvertHitObject : HitObject { public override Judgement CreateJudgement() => new IgnoreJudgement(); From 36079236e6d96ea1c3a688e662cee9de4e6e0fe4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Feb 2020 19:22:51 +0900 Subject: [PATCH 37/43] Remove pointless comment Co-Authored-By: Dan Balasescu --- osu.Game/Rulesets/Objects/HitObject.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 477d025253..9a8efdde84 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -144,7 +144,6 @@ namespace osu.Game.Rulesets.Objects /// /// Creates the that represents the scoring information for this . - /// Used to decide on drawable object lifetimes. /// [NotNull] public virtual Judgement CreateJudgement() => new Judgement(); From b872f782e7eae6fe381c2c9f32666626326e4d49 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Feb 2020 20:04:39 +0900 Subject: [PATCH 38/43] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 939d179b1d..24afbb86fb 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 24ee25c4de..c5ebf0f712 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 3743138c1a..9574b8cba9 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 9557a2cd9659fdc565fa95510d7f6b49c71337d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Feb 2020 20:52:33 +0900 Subject: [PATCH 39/43] Use object initialiser --- osu.Game/Screens/Edit/Editor.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8d3b8849bc..3a6f02f811 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -93,9 +93,10 @@ namespace osu.Game.Screens.Edit EditorMenuBar menuBar; - var fileMenuItems = new List(); - - fileMenuItems.Add(new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap)); + var fileMenuItems = new List + { + new EditorMenuItem("Save", MenuItemType.Standard, saveBeatmap) + }; if (RuntimeInfo.IsDesktop) fileMenuItems.Add(new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap)); From 535a7989d613538564df1ed650968bf56d49d965 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 25 Feb 2020 20:57:15 +0100 Subject: [PATCH 40/43] Open rankings overlay on spotlights page. --- osu.Game/Overlays/RankingsOverlay.cs | 6 ++++++ osu.Game/Screens/Menu/MainMenu.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 3304c6ebec..afb23883ac 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -138,6 +138,12 @@ namespace osu.Game.Overlays Country.Value = requested; } + public void ShowSpotlights() + { + Scope.Value = RankingsScope.Spotlights; + Show(); + } + private void loadNewContent() { loading.Show(); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index af5db4ce8c..127270f521 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -134,7 +134,7 @@ namespace osu.Game.Screens.Menu buttons.OnSettings = () => settings?.ToggleVisibility(); buttons.OnDirect = () => direct?.ToggleVisibility(); - buttons.OnChart = () => rankings?.ToggleVisibility(); + buttons.OnChart = () => rankings?.ShowSpotlights(); LoadComponentAsync(background = new BackgroundScreenDefault()); preloadSongSelect(); From 88ec31c262e7d8fefe84d90babb7358a9ebd13c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Feb 2020 22:39:20 +0100 Subject: [PATCH 41/43] Add tests demonstrating crash --- .../TestSceneBananaShower.cs | 8 ++- .../TestSceneJuiceStream.cs | 56 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs index 56e378d19e..20911b8d06 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs @@ -29,6 +29,12 @@ namespace osu.Game.Rulesets.Catch.Tests { } + [Test] + public void TestBananaShower() + { + AddUntilStep("player is done", () => !Player.ValidForResume); + } + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { var beatmap = new Beatmap @@ -40,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Tests } }; - beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 5000, NewCombo = true }); + beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 3000, NewCombo = true }); return beatmap; } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs new file mode 100644 index 0000000000..cbc87459e1 --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Tests.Visual; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Tests +{ + public class TestSceneJuiceStream : PlayerTestScene + { + public TestSceneJuiceStream() + : base(new CatchRuleset()) + { + } + + [Test] + public void TestJuiceStreamEndingCombo() + { + AddUntilStep("player is done", () => !Player.ValidForResume); + } + + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty { CircleSize = 5, SliderMultiplier = 2 }, + Ruleset = ruleset + }, + HitObjects = new List + { + new JuiceStream + { + X = 0.5f, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(0, 100) + }), + StartTime = 200 + }, + new Banana + { + X = 0.5f, + StartTime = 1000, + NewCombo = true + } + } + }; + } +} From bf36dc10a561b02bad1399a6c3a0991572173a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Feb 2020 23:13:32 +0100 Subject: [PATCH 42/43] Fix invalid cast Since introduction of IgnoreJudgement and its usage in JuiceStream and BananaShower the hard cast in CatcherArea that was used to check if the drawable hit object should cause the fruits on the plate explode at the end of combo caused a hard crash instead, since IgnoreJudgement was no longer deriving from CatchJudgement. Replace the hard cast with a soft pattern-matched cast. --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index ff2471f8bf..0b3809150a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Catch.UI if (fruit.HitObject.LastInCombo) { - if (((CatchJudgement)result.Judgement).ShouldExplodeFor(result)) + if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result)) runAfterLoaded(() => MovableCatcher.Explode()); else MovableCatcher.Drop(); From fab49fb1ba593f6a1c7da84afae5605871e77f53 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 26 Feb 2020 12:18:46 +0900 Subject: [PATCH 43/43] Slightly increase HP awarded for 100s --- osu.Game/Rulesets/Judgements/Judgement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 599135ba54..9105b920ca 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Judgements return -DEFAULT_MAX_HEALTH_INCREASE * 0.01; case HitResult.Good: - return DEFAULT_MAX_HEALTH_INCREASE * 0.3; + return DEFAULT_MAX_HEALTH_INCREASE * 0.5; case HitResult.Great: return DEFAULT_MAX_HEALTH_INCREASE;