Merge branch 'master' into player-loader-star-rating

This commit is contained in:
Dean Herbert 2021-05-10 12:46:10 +09:00 committed by GitHub
commit 52ce16f9f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 266 additions and 289 deletions

View File

@ -52,6 +52,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.506.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2021.507.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -26,6 +26,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
{ {
AccentColour = Color4.Transparent AccentColour = Color4.Transparent
}; };
// SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur.
// Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling.
AlwaysPresent = true;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -4,9 +4,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
namespace osu.Game.Tests.Visual.Gameplay namespace osu.Game.Tests.Visual.Gameplay
@ -17,31 +19,21 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
[Cached]
private ScoreProcessor scoreProcessor = new ScoreProcessor();
[SetUpSteps] [SetUpSteps]
public void SetUpSteps() public void SetUpSteps()
{ {
AddStep("Create combo counters", () => SetContents(() => AddStep("Create combo counters", () => SetContents(() => new SkinnableComboCounter()));
{
var comboCounter = new SkinnableComboCounter();
comboCounter.Current.Value = 1;
return comboCounter;
}));
} }
[Test] [Test]
public void TestComboCounterIncrementing() public void TestComboCounterIncrementing()
{ {
AddRepeatStep("increase combo", () => AddRepeatStep("increase combo", () => scoreProcessor.Combo.Value++, 10);
{
foreach (var counter in comboCounters)
counter.Current.Value++;
}, 10);
AddStep("reset combo", () => AddStep("reset combo", () => scoreProcessor.Combo.Value = 0);
{
foreach (var counter in comboCounters)
counter.Current.Value = 0;
});
} }
} }
} }

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osuTK.Input; using osuTK.Input;
@ -19,6 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
private HUDOverlay hudOverlay; private HUDOverlay hudOverlay;
[Cached]
private ScoreProcessor scoreProcessor = new ScoreProcessor();
// best way to check without exposing. // best way to check without exposing.
private Drawable hideTarget => hudOverlay.KeyCounter; private Drawable hideTarget => hudOverlay.KeyCounter;
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First(); private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
@ -31,9 +35,9 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
createNew(); createNew();
AddRepeatStep("increase combo", () => { hudOverlay.ComboCounter.Current.Value++; }, 10); AddRepeatStep("increase combo", () => { scoreProcessor.Combo.Value++; }, 10);
AddStep("reset combo", () => { hudOverlay.ComboCounter.Current.Value = 0; }); AddStep("reset combo", () => { scoreProcessor.Combo.Value = 0; });
} }
[Test] [Test]
@ -139,12 +143,12 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
AddStep("create overlay", () => AddStep("create overlay", () =>
{ {
hudOverlay = new HUDOverlay(null, null, null, Array.Empty<Mod>()); hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
// Add any key just to display the key counter visually. // Add any key just to display the key counter visually.
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
hudOverlay.ComboCounter.Current.Value = 1; scoreProcessor.Combo.Value = 1;
action?.Invoke(hudOverlay); action?.Invoke(hudOverlay);

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -17,6 +18,9 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene
{ {
[Cached]
private readonly ScoreProcessor scoreProcessor = new ScoreProcessor();
[SetUpSteps] [SetUpSteps]
public void SetUpSteps() public void SetUpSteps()
{ {
@ -28,8 +32,6 @@ namespace osu.Game.Tests.Visual.Gameplay
var working = CreateWorkingBeatmap(ruleset.RulesetInfo); var working = CreateWorkingBeatmap(ruleset.RulesetInfo);
var beatmap = working.GetPlayableBeatmap(ruleset.RulesetInfo); var beatmap = working.GetPlayableBeatmap(ruleset.RulesetInfo);
ScoreProcessor scoreProcessor = new ScoreProcessor();
var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap); var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap);
var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty<Mod>()) var hudOverlay = new HUDOverlay(scoreProcessor, null, drawableRuleset, Array.Empty<Mod>())
@ -40,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay
// Add any key just to display the key counter visually. // Add any key just to display the key counter visually.
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
hudOverlay.ComboCounter.Current.Value = 1; scoreProcessor.Combo.Value = 1;
return new Container return new Container
{ {

View File

@ -1,49 +1,36 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
namespace osu.Game.Tests.Visual.Gameplay namespace osu.Game.Tests.Visual.Gameplay
{ {
public class TestSceneSkinnableAccuracyCounter : SkinnableTestScene public class TestSceneSkinnableAccuracyCounter : SkinnableTestScene
{ {
private IEnumerable<SkinnableAccuracyCounter> accuracyCounters => CreatedDrawables.OfType<SkinnableAccuracyCounter>();
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
[Cached]
private ScoreProcessor scoreProcessor = new ScoreProcessor();
[SetUpSteps] [SetUpSteps]
public void SetUpSteps() public void SetUpSteps()
{ {
AddStep("Create combo counters", () => SetContents(() => AddStep("Set initial accuracy", () => scoreProcessor.Accuracy.Value = 1);
{ AddStep("Create accuracy counters", () => SetContents(() => new SkinnableAccuracyCounter()));
var accuracyCounter = new SkinnableAccuracyCounter();
accuracyCounter.Current.Value = 1;
return accuracyCounter;
}));
} }
[Test] [Test]
public void TestChangingAccuracy() public void TestChangingAccuracy()
{ {
AddStep(@"Reset all", delegate AddStep(@"Reset all", () => scoreProcessor.Accuracy.Value = 1);
{
foreach (var s in accuracyCounters)
s.Current.Value = 1;
});
AddStep(@"Hit! :D", delegate AddStep(@"Miss :(", () => scoreProcessor.Accuracy.Value -= 0.023);
{
foreach (var s in accuracyCounters)
s.Current.Value -= 0.023f;
});
} }
} }
} }

View File

@ -14,6 +14,7 @@ using osu.Game.Configuration;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osuTK.Input; using osuTK.Input;
@ -23,6 +24,9 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
private HUDOverlay hudOverlay; private HUDOverlay hudOverlay;
[Cached]
private ScoreProcessor scoreProcessor = new ScoreProcessor();
private IEnumerable<HUDOverlay> hudOverlays => CreatedDrawables.OfType<HUDOverlay>(); private IEnumerable<HUDOverlay> hudOverlays => CreatedDrawables.OfType<HUDOverlay>();
// best way to check without exposing. // best way to check without exposing.
@ -37,17 +41,9 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
createNew(); createNew();
AddRepeatStep("increase combo", () => AddRepeatStep("increase combo", () => scoreProcessor.Combo.Value++, 10);
{
foreach (var hud in hudOverlays)
hud.ComboCounter.Current.Value++;
}, 10);
AddStep("reset combo", () => AddStep("reset combo", () => scoreProcessor.Combo.Value = 0);
{
foreach (var hud in hudOverlays)
hud.ComboCounter.Current.Value = 0;
});
} }
[Test] [Test]
@ -80,13 +76,11 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
SetContents(() => SetContents(() =>
{ {
hudOverlay = new HUDOverlay(null, null, null, Array.Empty<Mod>()); hudOverlay = new HUDOverlay(scoreProcessor, null, null, Array.Empty<Mod>());
// Add any key just to display the key counter visually. // Add any key just to display the key counter visually.
hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space));
hudOverlay.ComboCounter.Current.Value = 1;
action?.Invoke(hudOverlay); action?.Invoke(hudOverlay);
return hudOverlay; return hudOverlay;

View File

@ -4,10 +4,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
namespace osu.Game.Tests.Visual.Gameplay namespace osu.Game.Tests.Visual.Gameplay
@ -18,37 +20,27 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
[Cached]
private ScoreProcessor scoreProcessor = new ScoreProcessor();
[SetUpSteps] [SetUpSteps]
public void SetUpSteps() public void SetUpSteps()
{ {
AddStep("Create combo counters", () => SetContents(() => AddStep("Create score counters", () => SetContents(() => new SkinnableScoreCounter()));
{
var comboCounter = new SkinnableScoreCounter();
comboCounter.Current.Value = 1;
return comboCounter;
}));
} }
[Test] [Test]
public void TestScoreCounterIncrementing() public void TestScoreCounterIncrementing()
{ {
AddStep(@"Reset all", delegate AddStep(@"Reset all", () => scoreProcessor.TotalScore.Value = 0);
{
foreach (var s in scoreCounters)
s.Current.Value = 0;
});
AddStep(@"Hit! :D", delegate AddStep(@"Hit! :D", () => scoreProcessor.TotalScore.Value += 300);
{
foreach (var s in scoreCounters)
s.Current.Value += 300;
});
} }
[Test] [Test]
public void TestVeryLargeScore() public void TestVeryLargeScore()
{ {
AddStep("set large score", () => scoreCounters.ForEach(counter => counter.Current.Value = 1_000_000_000)); AddStep("set large score", () => scoreCounters.ForEach(counter => scoreProcessor.TotalScore.Value = 1_000_000_000));
} }
} }
} }

View File

@ -133,6 +133,16 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= currentStoryboardDuration); AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= currentStoryboardDuration);
} }
[Test]
public void TestPerformExitNoOutro()
{
CreateTest(null);
AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false));
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
AddStep("exit via pause", () => Player.ExitViaPause());
AddAssert("player exited", () => Stack.CurrentScreen == null);
}
protected override bool AllowFail => true; protected override bool AllowFail => true;
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();

View File

@ -2,7 +2,10 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
@ -14,21 +17,34 @@ namespace osu.Game.Tests.Visual.Online
{ {
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
private NewsOverlay news; private NewsOverlay overlay;
[SetUp] [SetUp]
public void SetUp() => Schedule(() => Child = news = new NewsOverlay()); public void SetUp() => Schedule(() => Child = overlay = new NewsOverlay());
[Test] [Test]
public void TestRequest() public void TestRequest()
{ {
setUpNewsResponse(responseExample); setUpNewsResponse(responseExample);
AddStep("Show", () => news.Show()); AddStep("Show", () => overlay.Show());
AddStep("Show article", () => news.ShowArticle("article")); AddStep("Show article", () => overlay.ShowArticle("article"));
} }
private void setUpNewsResponse(GetNewsResponse r) [Test]
=> AddStep("set up response", () => public void TestCursorRequest()
{
setUpNewsResponse(responseWithCursor, "Set up cursor response");
AddStep("Show", () => overlay.Show());
AddUntilStep("Show More button is visible", () => showMoreButton?.Alpha == 1);
setUpNewsResponse(responseWithNoCursor, "Set up no cursor response");
AddStep("Click Show More", () => showMoreButton?.Click());
AddUntilStep("Show More button is hidden", () => showMoreButton?.Alpha == 0);
}
private ShowMoreButton showMoreButton => overlay.ChildrenOfType<ShowMoreButton>().FirstOrDefault();
private void setUpNewsResponse(GetNewsResponse r, string testName = "Set up response")
=> AddStep(testName, () =>
{ {
dummyAPI.HandleRequest = request => dummyAPI.HandleRequest = request =>
{ {
@ -40,7 +56,7 @@ namespace osu.Game.Tests.Visual.Online
}; };
}); });
private GetNewsResponse responseExample => new GetNewsResponse private static GetNewsResponse responseExample => new GetNewsResponse
{ {
NewsPosts = new[] NewsPosts = new[]
{ {
@ -62,5 +78,37 @@ namespace osu.Game.Tests.Visual.Online
} }
} }
}; };
private static GetNewsResponse responseWithCursor => new GetNewsResponse
{
NewsPosts = new[]
{
new APINewsPost
{
Title = "This post has an image which starts with \"/\" and has many authors!",
Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
Author = "someone, someone1, someone2, someone3, someone4",
FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png",
PublishedAt = DateTimeOffset.Now
}
},
Cursor = new Cursor()
};
private static GetNewsResponse responseWithNoCursor => new GetNewsResponse
{
NewsPosts = new[]
{
new APINewsPost
{
Title = "This post has a full-url image! (HTML entity: &amp;)",
Preview = "boom (HTML entity: &amp;)",
Author = "user (HTML entity: &amp;)",
FirstImage = "https://assets.ppy.sh/artists/88/header.jpg",
PublishedAt = DateTimeOffset.Now
}
},
Cursor = null
};
} }
} }

View File

@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("check version", () => infoWedge.Info.VersionLabel.Current.Value == $"{ruleset.ShortName}Version"); AddAssert("check version", () => infoWedge.Info.VersionLabel.Current.Value == $"{ruleset.ShortName}Version");
AddAssert("check title", () => infoWedge.Info.TitleLabel.Current.Value == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); AddAssert("check title", () => infoWedge.Info.TitleLabel.Current.Value == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title");
AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Current.Value == $"{ruleset.ShortName}Artist"); AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Current.Value == $"{ruleset.ShortName}Artist");
AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType<OsuSpriteText>().Any(s => s.Current.Value == $"{ruleset.ShortName}Author")); AddAssert("check author", () => infoWedge.Info.MapperContainer.ChildrenOfType<OsuSpriteText>().Any(s => s.Current.Value == $"{ruleset.ShortName}Author"));
} }
private void testInfoLabels(int expectedCount) private void testInfoLabels(int expectedCount)
@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Current.Value)); AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Current.Value));
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default title", () => infoWedge.Info.TitleLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Title);
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Artist); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Artist);
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.ChildrenOfType<OsuSpriteText>().Any());
AddAssert("check no info labels", () => !infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any()); AddAssert("check no info labels", () => !infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
} }

View File

@ -304,6 +304,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Sort by BPM", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.BPM)); AddStep(@"Sort by BPM", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.BPM));
AddStep(@"Sort by Length", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Length)); AddStep(@"Sort by Length", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Length));
AddStep(@"Sort by Difficulty", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Difficulty)); AddStep(@"Sort by Difficulty", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Difficulty));
AddStep(@"Sort by Source", () => config.SetValue(OsuSetting.SongSelectSortingMode, SortMode.Source));
} }
[Test] [Test]

View File

@ -4,11 +4,10 @@
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Play.HUD;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public abstract class ScoreCounter : RollingCounter<double>, IScoreCounter public abstract class ScoreCounter : RollingCounter<double>
{ {
protected override double RollingDuration => 1000; protected override double RollingDuration => 1000;
protected override Easing RollingEasing => Easing.Out; protected override Easing RollingEasing => Easing.Out;

View File

@ -23,6 +23,8 @@ namespace osu.Game.Online.API.Requests
return req; return req;
} }
protected override string FileExtension => ".osz";
protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}"; protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}";
} }
} }

View File

@ -13,6 +13,8 @@ using osuTK.Graphics;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Users;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.BeatmapSet namespace osu.Game.Overlays.BeatmapSet
{ {
@ -50,7 +52,7 @@ namespace osu.Game.Overlays.BeatmapSet
fields.Children = new Drawable[] fields.Children = new Drawable[]
{ {
new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), new Field("mapped by", BeatmapSet.Metadata.Author, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)),
new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold)) new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold))
{ {
Margin = new MarginPadding { Top = 5 }, Margin = new MarginPadding { Top = 5 },
@ -146,6 +148,25 @@ namespace osu.Game.Overlays.BeatmapSet
} }
}; };
} }
public Field(string first, User second, FontUsage secondFont)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Children = new[]
{
new LinkFlowContainer(s =>
{
s.Font = OsuFont.GetFont(size: 11);
}).With(d =>
{
d.AutoSizeAxes = Axes.Both;
d.AddText($"{first} ");
d.AddUserLink(second, s => s.Font = secondFont.With(size: 11));
}),
};
}
} }
} }
} }

View File

@ -100,7 +100,7 @@ namespace osu.Game.Overlays.News.Displays
{ {
content.Add(loaded); content.Add(loaded);
showMore.IsLoading = false; showMore.IsLoading = false;
showMore.Show(); showMore.Alpha = lastCursor == null ? 0 : 1;
}, (cancellationToken = new CancellationTokenSource()).Token); }, (cancellationToken = new CancellationTokenSource()).Token);
} }

View File

@ -204,7 +204,7 @@ namespace osu.Game.Overlays.Volume
{ {
displayVolume = value; displayVolume = value;
if (displayVolume > 0.99f) if (displayVolume >= 0.995f)
{ {
text.Text = "MAX"; text.Text = "MAX";
maxGlow.EffectColour = meterColour.Opacity(2f); maxGlow.EffectColour = meterColour.Opacity(2f);

View File

@ -17,7 +17,6 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -144,8 +143,7 @@ namespace osu.Game.Screens.Edit
// Todo: should probably be done at a DrawableRuleset level to share logic with Player. // Todo: should probably be done at a DrawableRuleset level to share logic with Player.
clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false };
clock.ChangeSource(loadableBeatmap.Track);
UpdateClockSource();
dependencies.CacheAs(clock); dependencies.CacheAs(clock);
AddInternal(clock); AddInternal(clock);
@ -308,11 +306,7 @@ namespace osu.Game.Screens.Edit
/// <summary> /// <summary>
/// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state.
/// </summary> /// </summary>
public void UpdateClockSource() public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track);
{
var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock();
clock.ChangeSource(sourceClock);
}
protected void Save() protected void Save()
{ {
@ -583,7 +577,7 @@ namespace osu.Game.Screens.Edit
private void resetTrack(bool seekToStart = false) private void resetTrack(bool seekToStart = false)
{ {
Beatmap.Value.Track?.Stop(); Beatmap.Value.Track.Stop();
if (seekToStart) if (seekToStart)
{ {

View File

@ -4,12 +4,11 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osuTK; using osuTK;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class DefaultAccuracyCounter : PercentageCounter, IAccuracyCounter, ISkinnableComponent public class DefaultAccuracyCounter : GameplayAccuracyCounter, ISkinnableComponent
{ {
private readonly Vector2 offset = new Vector2(-20, 5); private readonly Vector2 offset = new Vector2(-20, 5);

View File

@ -7,11 +7,12 @@ using osu.Framework.Graphics;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Scoring;
using osuTK; using osuTK;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class DefaultComboCounter : RollingCounter<int>, IComboCounter, ISkinnableComponent public class DefaultComboCounter : RollingCounter<int>, ISkinnableComponent
{ {
private readonly Vector2 offset = new Vector2(20, 5); private readonly Vector2 offset = new Vector2(20, 5);
@ -24,7 +25,11 @@ namespace osu.Game.Screens.Play.HUD
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) => Colour = colours.BlueLighter; private void load(OsuColour colours, ScoreProcessor scoreProcessor)
{
Colour = colours.BlueLighter;
Current.BindTo(scoreProcessor.Combo);
}
protected override void Update() protected override void Update()
{ {

View File

@ -4,11 +4,10 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class DefaultScoreCounter : ScoreCounter, ISkinnableComponent public class DefaultScoreCounter : GameplayScoreCounter, ISkinnableComponent
{ {
public DefaultScoreCounter() public DefaultScoreCounter()
: base(6) : base(6)

View File

@ -0,0 +1,18 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Play.HUD
{
public abstract class GameplayAccuracyCounter : PercentageCounter
{
[BackgroundDependencyLoader]
private void load(ScoreProcessor scoreProcessor)
{
Current.BindTo(scoreProcessor.Accuracy);
}
}
}

View File

@ -0,0 +1,46 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Play.HUD
{
public abstract class GameplayScoreCounter : ScoreCounter
{
private Bindable<ScoringMode> scoreDisplayMode;
protected GameplayScoreCounter(int leading = 0, bool useCommaSeparator = false)
: base(leading, useCommaSeparator)
{
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, ScoreProcessor scoreProcessor)
{
scoreDisplayMode = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode);
scoreDisplayMode.BindValueChanged(scoreMode =>
{
switch (scoreMode.NewValue)
{
case ScoringMode.Standardised:
RequiredDisplayDigits.Value = 6;
break;
case ScoringMode.Classic:
RequiredDisplayDigits.Value = 8;
break;
default:
throw new ArgumentOutOfRangeException(nameof(scoreMode));
}
}, true);
Current.BindTo(scoreProcessor.TotalScore);
}
}
}

View File

@ -1,19 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Play.HUD
{
/// <summary>
/// An interface providing a set of methods to update a accuracy counter.
/// </summary>
public interface IAccuracyCounter : IDrawable
{
/// <summary>
/// The current accuracy to be displayed.
/// </summary>
Bindable<double> Current { get; }
}
}

View File

@ -1,19 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Play.HUD
{
/// <summary>
/// An interface providing a set of methods to update a combo counter.
/// </summary>
public interface IComboCounter : IDrawable
{
/// <summary>
/// The current combo to be displayed.
/// </summary>
Bindable<int> Current { get; }
}
}

View File

@ -1,25 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Play.HUD
{
/// <summary>
/// An interface providing a set of methods to update a score counter.
/// </summary>
public interface IScoreCounter : IDrawable
{
/// <summary>
/// The current score to be displayed.
/// </summary>
Bindable<double> Current { get; }
/// <summary>
/// The number of digits required to display most sane scores.
/// This may be exceeded in very rare cases, but is useful to pad or space the display to avoid it jumping around.
/// </summary>
Bindable<int> RequiredDisplayDigits { get; }
}
}

View File

@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -14,7 +15,7 @@ namespace osu.Game.Screens.Play.HUD
/// <summary> /// <summary>
/// Uses the 'x' symbol and has a pop-out effect while rolling over. /// Uses the 'x' symbol and has a pop-out effect while rolling over.
/// </summary> /// </summary>
public class LegacyComboCounter : CompositeDrawable, IComboCounter, ISkinnableComponent public class LegacyComboCounter : CompositeDrawable, ISkinnableComponent
{ {
public Bindable<int> Current { get; } = new BindableInt { MinValue = 0, }; public Bindable<int> Current { get; } = new BindableInt { MinValue = 0, };
@ -79,7 +80,7 @@ namespace osu.Game.Screens.Play.HUD
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load(ScoreProcessor scoreProcessor)
{ {
InternalChildren = new[] InternalChildren = new[]
{ {
@ -95,7 +96,7 @@ namespace osu.Game.Screens.Play.HUD
}, },
}; };
Current.ValueChanged += combo => updateCount(combo.NewValue == 0); Current.BindTo(scoreProcessor.Combo);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -109,7 +110,7 @@ namespace osu.Game.Screens.Play.HUD
popOutCount.Origin = Origin; popOutCount.Origin = Origin;
popOutCount.Anchor = Anchor; popOutCount.Anchor = Anchor;
updateCount(false); Current.BindValueChanged(combo => updateCount(combo.NewValue == 0), true);
} }
private void updateCount(bool rolling) private void updateCount(bool rolling)

View File

@ -1,29 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class SkinnableAccuracyCounter : SkinnableDrawable, IAccuracyCounter public class SkinnableAccuracyCounter : SkinnableDrawable
{ {
public Bindable<double> Current { get; } = new Bindable<double>();
public SkinnableAccuracyCounter() public SkinnableAccuracyCounter()
: base(new HUDSkinComponent(HUDSkinComponents.AccuracyCounter), _ => new DefaultAccuracyCounter()) : base(new HUDSkinComponent(HUDSkinComponents.AccuracyCounter), _ => new DefaultAccuracyCounter())
{ {
CentreComponent = false; CentreComponent = false;
} }
private IAccuracyCounter skinnedCounter;
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
skinnedCounter = Drawable as IAccuracyCounter;
skinnedCounter?.Current.BindTo(Current);
}
} }
} }

View File

@ -1,29 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class SkinnableComboCounter : SkinnableDrawable, IComboCounter public class SkinnableComboCounter : SkinnableDrawable
{ {
public Bindable<int> Current { get; } = new Bindable<int>();
public SkinnableComboCounter() public SkinnableComboCounter()
: base(new HUDSkinComponent(HUDSkinComponents.ComboCounter), skinComponent => new DefaultComboCounter()) : base(new HUDSkinComponent(HUDSkinComponents.ComboCounter), skinComponent => new DefaultComboCounter())
{ {
CentreComponent = false; CentreComponent = false;
} }
private IComboCounter skinnedCounter;
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
skinnedCounter = Drawable as IComboCounter;
skinnedCounter?.Current.BindTo(Current);
}
} }
} }

View File

@ -1,61 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD namespace osu.Game.Screens.Play.HUD
{ {
public class SkinnableScoreCounter : SkinnableDrawable, IScoreCounter public class SkinnableScoreCounter : SkinnableDrawable
{ {
public Bindable<double> Current { get; } = new Bindable<double>();
private Bindable<ScoringMode> scoreDisplayMode;
public Bindable<int> RequiredDisplayDigits { get; } = new Bindable<int>();
public SkinnableScoreCounter() public SkinnableScoreCounter()
: base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter()) : base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter())
{ {
CentreComponent = false; CentreComponent = false;
} }
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
scoreDisplayMode = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode);
scoreDisplayMode.BindValueChanged(scoreMode =>
{
switch (scoreMode.NewValue)
{
case ScoringMode.Standardised:
RequiredDisplayDigits.Value = 6;
break;
case ScoringMode.Classic:
RequiredDisplayDigits.Value = 8;
break;
default:
throw new ArgumentOutOfRangeException(nameof(scoreMode));
}
}, true);
}
private IScoreCounter skinnedCounter;
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
skinnedCounter = Drawable as IScoreCounter;
skinnedCounter?.Current.BindTo(Current);
skinnedCounter?.RequiredDisplayDigits.BindTo(RequiredDisplayDigits);
}
} }
} }

View File

@ -34,7 +34,6 @@ namespace osu.Game.Screens.Play
public float TopScoringElementsHeight { get; private set; } public float TopScoringElementsHeight { get; private set; }
public readonly KeyCounterDisplay KeyCounter; public readonly KeyCounterDisplay KeyCounter;
public readonly SkinnableComboCounter ComboCounter;
public readonly SkinnableScoreCounter ScoreCounter; public readonly SkinnableScoreCounter ScoreCounter;
public readonly SkinnableAccuracyCounter AccuracyCounter; public readonly SkinnableAccuracyCounter AccuracyCounter;
public readonly SkinnableHealthDisplay HealthDisplay; public readonly SkinnableHealthDisplay HealthDisplay;
@ -106,7 +105,7 @@ namespace osu.Game.Screens.Play
HealthDisplay = CreateHealthDisplay(), HealthDisplay = CreateHealthDisplay(),
AccuracyCounter = CreateAccuracyCounter(), AccuracyCounter = CreateAccuracyCounter(),
ScoreCounter = CreateScoreCounter(), ScoreCounter = CreateScoreCounter(),
ComboCounter = CreateComboCounter(), CreateComboCounter(),
HitErrorDisplay = CreateHitErrorDisplayOverlay(), HitErrorDisplay = CreateHitErrorDisplayOverlay(),
} }
}, },
@ -276,13 +275,13 @@ namespace osu.Game.Screens.Play
Progress.BindDrawableRuleset(drawableRuleset); Progress.BindDrawableRuleset(drawableRuleset);
} }
protected virtual SkinnableAccuracyCounter CreateAccuracyCounter() => new SkinnableAccuracyCounter(); protected SkinnableAccuracyCounter CreateAccuracyCounter() => new SkinnableAccuracyCounter();
protected virtual SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter(); protected SkinnableScoreCounter CreateScoreCounter() => new SkinnableScoreCounter();
protected virtual SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter(); protected SkinnableComboCounter CreateComboCounter() => new SkinnableComboCounter();
protected virtual SkinnableHealthDisplay CreateHealthDisplay() => new SkinnableHealthDisplay(); protected SkinnableHealthDisplay CreateHealthDisplay() => new SkinnableHealthDisplay();
protected virtual FailingLayer CreateFailingLayer() => new FailingLayer protected virtual FailingLayer CreateFailingLayer() => new FailingLayer
{ {
@ -321,10 +320,6 @@ namespace osu.Game.Screens.Play
protected virtual void BindScoreProcessor(ScoreProcessor processor) protected virtual void BindScoreProcessor(ScoreProcessor processor)
{ {
ScoreCounter?.Current.BindTo(processor.TotalScore);
AccuracyCounter?.Current.BindTo(processor.Accuracy);
ComboCounter?.Current.BindTo(processor.Combo);
if (HealthDisplay is IHealthDisplay shd) if (HealthDisplay is IHealthDisplay shd)
{ {
processor.NewJudgement += judgement => processor.NewJudgement += judgement =>

View File

@ -203,6 +203,8 @@ namespace osu.Game.Screens.Play
ScoreProcessor.ApplyBeatmap(playableBeatmap); ScoreProcessor.ApplyBeatmap(playableBeatmap);
ScoreProcessor.Mods.BindTo(Mods); ScoreProcessor.Mods.BindTo(Mods);
dependencies.CacheAs(ScoreProcessor);
HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
HealthProcessor.ApplyBeatmap(playableBeatmap); HealthProcessor.ApplyBeatmap(playableBeatmap);
@ -541,8 +543,10 @@ namespace osu.Game.Screens.Play
} }
// if the score is ready for display but results screen has not been pushed yet (e.g. storyboard is still playing beyond gameplay), then transition to results screen instead of exiting. // if the score is ready for display but results screen has not been pushed yet (e.g. storyboard is still playing beyond gameplay), then transition to results screen instead of exiting.
if (prepareScoreForDisplayTask != null) if (prepareScoreForDisplayTask != null && completionProgressDelegate == null)
{
updateCompletionState(true); updateCompletionState(true);
}
} }
this.Exit(); this.Exit();

View File

@ -28,6 +28,7 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Screens.Ranking.Expanded; using osu.Game.Screens.Ranking.Expanded;
using osu.Game.Graphics.Containers;
namespace osu.Game.Screens.Select namespace osu.Game.Screens.Select
{ {
@ -286,7 +287,7 @@ namespace osu.Game.Screens.Select
Margin = new MarginPadding { Top = 10 }, Margin = new MarginPadding { Top = 10 },
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = getMapper(metadata) Child = getMapper(metadata),
}, },
infoLabelContainer = new FillFlowContainer infoLabelContainer = new FillFlowContainer
{ {
@ -406,24 +407,20 @@ namespace osu.Game.Screens.Select
}); });
} }
private OsuSpriteText[] getMapper(BeatmapMetadata metadata) private Drawable getMapper(BeatmapMetadata metadata)
{ {
if (string.IsNullOrEmpty(metadata.Author?.Username)) if (metadata.Author == null)
return Array.Empty<OsuSpriteText>(); return Empty();
return new[] return new LinkFlowContainer(s =>
{ {
new OsuSpriteText s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15);
{ }).With(d =>
Text = "mapped by ", {
Font = OsuFont.GetFont(size: 15), d.AutoSizeAxes = Axes.Both;
}, d.AddText("mapped by ");
new OsuSpriteText d.AddUserLink(metadata.Author);
{ });
Text = metadata.Author.Username,
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15),
}
};
} }
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)

View File

@ -71,6 +71,9 @@ namespace osu.Game.Screens.Select.Carousel
case SortMode.Author: case SortMode.Author:
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase); return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase);
case SortMode.Source:
return string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase);
case SortMode.DateAdded: case SortMode.DateAdded:
return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded);

View File

@ -28,7 +28,10 @@ namespace osu.Game.Screens.Select.Filter
[Description("Rank Achieved")] [Description("Rank Achieved")]
RankAchieved, RankAchieved,
[Description("Source")]
Source,
[Description("Title")] [Description("Title")]
Title Title,
} }
} }

View File

@ -4,14 +4,13 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osuTK; using osuTK;
namespace osu.Game.Skinning namespace osu.Game.Skinning
{ {
public class LegacyAccuracyCounter : PercentageCounter, IAccuracyCounter, ISkinnableComponent public class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableComponent
{ {
private readonly ISkin skin; private readonly ISkin skin;

View File

@ -1,24 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osuTK; using osuTK;
namespace osu.Game.Skinning namespace osu.Game.Skinning
{ {
public class LegacyScoreCounter : ScoreCounter, ISkinnableComponent public class LegacyScoreCounter : GameplayScoreCounter, ISkinnableComponent
{ {
private readonly ISkin skin; private readonly ISkin skin;
protected override double RollingDuration => 1000; protected override double RollingDuration => 1000;
protected override Easing RollingEasing => Easing.Out; protected override Easing RollingEasing => Easing.Out;
public new Bindable<double> Current { get; } = new Bindable<double>();
public LegacyScoreCounter(ISkin skin) public LegacyScoreCounter(ISkin skin)
: base(6) : base(6)
{ {
@ -27,9 +23,6 @@ namespace osu.Game.Skinning
this.skin = skin; this.skin = skin;
// base class uses int for display, but externally we bind to ScoreProcessor as a double for now.
Current.BindValueChanged(v => base.Current.Value = (int)v.NewValue);
Scale = new Vector2(0.96f); Scale = new Vector2(0.96f);
Margin = new MarginPadding(10); Margin = new MarginPadding(10);
} }

View File

@ -4,7 +4,6 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> e) private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> e)
{ {
Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo;
Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); Clock.ChangeSource(e.NewValue.Track);
Clock.ProcessFrame(); Clock.ProcessFrame();
} }

View File

@ -29,7 +29,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" /> <PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2021.506.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.507.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" />
<PackageReference Include="Sentry" Version="3.3.4" /> <PackageReference Include="Sentry" Version="3.3.4" />
<PackageReference Include="SharpCompress" Version="0.28.2" /> <PackageReference Include="SharpCompress" Version="0.28.2" />

View File

@ -70,7 +70,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.506.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2021.507.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2021.422.0" />
</ItemGroup> </ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) --> <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
@ -93,7 +93,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2021.506.0" /> <PackageReference Include="ppy.osu.Framework" Version="2021.507.0" />
<PackageReference Include="SharpCompress" Version="0.28.2" /> <PackageReference Include="SharpCompress" Version="0.28.2" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />