Skip to content

Commit d07facc

Browse files
committed
Add recommended difficulty numerical value near filter in beatmap listing
1 parent 7fcf3c7 commit d07facc

File tree

3 files changed

+78
-5
lines changed

3 files changed

+78
-5
lines changed

osu.Game/Beatmaps/DifficultyRecommender.cs

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ namespace osu.Game.Beatmaps
2020
/// </summary>
2121
public partial class DifficultyRecommender : Component
2222
{
23+
public event Action? StarRatingUpdated;
24+
2325
private readonly LocalUserStatisticsProvider statisticsProvider;
2426

2527
[Resolved]
@@ -77,8 +79,12 @@ private void updateMapping(RulesetInfo ruleset, UserStatistics statistics)
7779
{
7880
// algorithm taken from https://github.com/ppy/osu-web/blob/e6e2825516449e3d0f3f5e1852c6bdd3428c3437/app/Models/User.php#L1505
7981
recommendedDifficultyMapping[ruleset.ShortName] = Math.Pow((double)(statistics.PP ?? 0), 0.4) * 0.195;
82+
83+
StarRatingUpdated?.Invoke();
8084
}
8185

86+
public double GetRecommendedStarRatingFor(RulesetInfo ruleset) => recommendedDifficultyMapping[ruleset.ShortName];
87+
8288
/// <summary>
8389
/// Find the recommended difficulty from a selection of available difficulties for the current local user.
8490
/// </summary>

osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public APIBeatmapSet? BeatmapSet
6565
}
6666

6767
private readonly BeatmapSearchTextBox textBox;
68-
private readonly BeatmapSearchMultipleSelectionFilterRow<SearchGeneral> generalFilter;
68+
private readonly BeatmapSearchGeneralFilterRow generalFilter;
6969
private readonly BeatmapSearchRulesetFilterRow modeFilter;
7070
private readonly BeatmapSearchFilterRow<SearchCategory> categoryFilter;
7171
private readonly BeatmapSearchFilterRow<SearchGenre> genreFilter;
@@ -163,6 +163,13 @@ private void load(OverlayColourProvider colourProvider, OsuConfigManager config)
163163
}, true);
164164
}
165165

166+
protected override void LoadComplete()
167+
{
168+
base.LoadComplete();
169+
170+
generalFilter.Ruleset.BindTo(Ruleset);
171+
}
172+
166173
public void TakeFocus() => textBox.TakeFocus();
167174

168175
private partial class BeatmapSearchTextBox : BasicSearchTextBox

osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs

+64-4
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,95 @@
44
using System;
55
using osu.Framework.Allocation;
66
using osu.Framework.Bindables;
7+
using osu.Framework.Extensions;
78
using osu.Framework.Graphics.Sprites;
89
using osu.Framework.Input.Events;
10+
using osu.Framework.Localisation;
11+
using osu.Game.Beatmaps;
912
using osu.Game.Configuration;
13+
using osu.Game.Extensions;
1014
using osu.Game.Graphics;
1115
using osu.Game.Localisation;
16+
using osu.Game.Online.API;
1217
using osu.Game.Overlays.Dialog;
1318
using osu.Game.Resources.Localisation.Web;
19+
using osu.Game.Rulesets;
20+
using osu.Game.Utils;
1421
using osuTK.Graphics;
1522
using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
1623

1724
namespace osu.Game.Overlays.BeatmapListing
1825
{
1926
public partial class BeatmapSearchGeneralFilterRow : BeatmapSearchMultipleSelectionFilterRow<SearchGeneral>
2027
{
28+
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
29+
2130
public BeatmapSearchGeneralFilterRow()
2231
: base(BeatmapsStrings.ListingSearchFiltersGeneral)
2332
{
2433
}
2534

26-
protected override MultipleSelectionFilter CreateMultipleSelectionFilter() => new GeneralFilter();
35+
protected override MultipleSelectionFilter CreateMultipleSelectionFilter() => new GeneralFilter
36+
{
37+
Ruleset = { BindTarget = Ruleset }
38+
};
2739

2840
private partial class GeneralFilter : MultipleSelectionFilter
2941
{
42+
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
43+
3044
protected override MultipleSelectionFilterTabItem CreateTabItem(SearchGeneral value)
3145
{
32-
if (value == SearchGeneral.FeaturedArtists)
33-
return new FeaturedArtistsTabItem();
46+
switch (value)
47+
{
48+
case SearchGeneral.Recommended:
49+
return new RecommendedDifficultyTabItem
50+
{
51+
Ruleset = { BindTarget = Ruleset }
52+
};
53+
54+
case SearchGeneral.FeaturedArtists:
55+
return new FeaturedArtistsTabItem();
56+
57+
default:
58+
return new MultipleSelectionFilterTabItem(value);
59+
}
60+
}
61+
}
62+
63+
private partial class RecommendedDifficultyTabItem : MultipleSelectionFilterTabItem
64+
{
65+
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
66+
67+
[Resolved]
68+
private DifficultyRecommender? recommender { get; set; }
69+
70+
[Resolved]
71+
private IAPIProvider api { get; set; } = null!;
72+
73+
[Resolved]
74+
private RulesetStore rulesets { get; set; } = null!;
75+
76+
public RecommendedDifficultyTabItem()
77+
: base(SearchGeneral.Recommended)
78+
{
79+
}
80+
81+
protected override void LoadComplete()
82+
{
83+
base.LoadComplete();
84+
85+
if (recommender != null) recommender.StarRatingUpdated += updateText;
3486

35-
return new MultipleSelectionFilterTabItem(value);
87+
Ruleset.BindValueChanged(_ => updateText(), true);
88+
}
89+
90+
private void updateText()
91+
{
92+
// fallback to profile default game mode if beatmap listing mode filter is set to Any
93+
// TODO: find a way to update `PlayMode` when the profile default game mode has changed
94+
var ruleset = Ruleset.Value.IsLegacyRuleset() ? Ruleset.Value : rulesets.GetRuleset(api.LocalUser.Value.PlayMode)!;
95+
Text.Text = LocalisableString.Interpolate($"{Value.GetLocalisableDescription()} ({recommender?.GetRecommendedStarRatingFor(ruleset).FormatStarRating()})");
3696
}
3797
}
3898

0 commit comments

Comments
 (0)