diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs b/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs index 88e381a46811..c6357a841dad 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs @@ -43,6 +43,8 @@ using osu.Game.Tests.Resources; using osu.Game.Users; using osuTK; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Catch.Mods; namespace osu.Game.Tests.Visual.Ranking { @@ -304,6 +306,29 @@ public void TestTaggingConvert() }); } + [Test] + public void TestTaggingConversionMods() + { + var score = TestResources.CreateTestScoreInfo(); + score.Mods = [new OsuModRandom()]; + + setUpTaggingRequests(() => score.BeatmapInfo); + AddStep("load panel", () => + { + Child = new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + Child = new StatisticsPanel + { + RelativeSizeAxes = Axes.Both, + State = { Value = Visibility.Visible }, + Score = { Value = score }, + AchievedScore = score, + } + }; + }); + } + [Test] public void TestTaggingInteractionWithLocalScores() { @@ -321,6 +346,7 @@ public void TestTaggingInteractionWithLocalScores() score.BeatmapInfo = beatmapInfo; score.BeatmapHash = beatmapInfo.Hash; score.Ruleset = beatmapInfo.Ruleset; + score.TotalScore = 999999; score.Rank = ScoreRank.D; score.User = API.LocalUser.Value; scoreManager.Import(score); @@ -332,7 +358,7 @@ public void TestTaggingInteractionWithLocalScores() score.BeatmapInfo = beatmapInfo; score.BeatmapHash = beatmapInfo.Hash; score.Ruleset = beatmapInfo.Ruleset; - score.Rank = ScoreRank.D; + score.Rank = ScoreRank.S; score.User = new APIUser { Username = "notme", Id = 5678 }; scoreManager.Import(score); }); @@ -342,17 +368,89 @@ public void TestTaggingInteractionWithLocalScores() var score = TestResources.CreateTestScoreInfo(); score.BeatmapInfo = beatmapInfo; score.BeatmapHash = beatmapInfo.Hash; + score.Rank = ScoreRank.A; score.Ruleset = new OsuRuleset().RulesetInfo; score.User = API.LocalUser.Value; scoreManager.Import(score); }); + AddStep("import incompatible mod score", () => + { + var score = TestResources.CreateTestScoreInfo(); + score.BeatmapInfo = beatmapInfo; + score.BeatmapHash = beatmapInfo.Hash; + score.Rank = ScoreRank.B; + score.Ruleset = beatmapInfo.Ruleset; + score.Mods = [new CatchModMirror()]; + score.User = API.LocalUser.Value; + scoreManager.Import(score); + }); + + AddStep("import correct score", () => + { + var score = TestResources.CreateTestScoreInfo(); + score.BeatmapInfo = beatmapInfo; + score.BeatmapHash = beatmapInfo.Hash; + score.TotalScore = 1; + score.Rank = ScoreRank.C; + score.Ruleset = beatmapInfo.Ruleset; + score.User = API.LocalUser.Value; + scoreManager.Import(score); + }); + + setUpTaggingRequests(() => beatmapInfo); + AddStep("load panel", () => + { + var score = TestResources.CreateTestScoreInfo(); + score.BeatmapInfo = beatmapInfo; + + Child = new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + Child = new StatisticsPanel + { + RelativeSizeAxes = Axes.Both, + State = { Value = Visibility.Visible }, + Score = { Value = score }, + } + }; + }); + } + + [Test] + public void TestTaggingScoreWithClassicMod() + { + BeatmapInfo beatmapInfo = null!; + + AddStep(@"Import beatmap", () => + { + beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); + beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First(); + beatmapInfo.Ruleset = new OsuRuleset().RulesetInfo; + }); + + AddStep("import incompatible score", () => + { + var score = TestResources.CreateTestScoreInfo(); + score.BeatmapInfo = beatmapInfo; + score.BeatmapHash = beatmapInfo.Hash; + score.Ruleset = beatmapInfo.Ruleset; + score.TotalScore = 1000000; + score.Rank = ScoreRank.S; + score.Mods = [new OsuModRandom()]; + score.User = API.LocalUser.Value; + scoreManager.Import(score); + }); + AddStep("import correct score", () => { var score = TestResources.CreateTestScoreInfo(); score.BeatmapInfo = beatmapInfo; score.BeatmapHash = beatmapInfo.Hash; score.Ruleset = beatmapInfo.Ruleset; + score.TotalScore = 999999; + score.Rank = ScoreRank.C; + score.Mods = [new OsuModClassic()]; score.User = API.LocalUser.Value; scoreManager.Import(score); }); diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 55e029f0410f..874dcb3ca84f 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -243,24 +243,34 @@ protected virtual IEnumerable CreateStatisticItems(ScoreInfo newS { string? preventTaggingReason = null; - // We may want to iterate on the following conditions further in the future - - var localUserScore = AchievedScore ?? realm.Run(r => + var localUserScores = realm.Run(r => r.GetAllLocalScoresForUser(api.LocalUser.Value.Id) .Filter($@"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0", newScore.BeatmapInfo.ID) .AsEnumerable() .OrderByDescending(score => score.Ruleset.MatchesOnlineID(newScore.BeatmapInfo.Ruleset)) - .ThenByDescending(score => score.Rank) - .FirstOrDefault()); + .ThenBy(score => score.Rank) + .ToArray()); - if (localUserScore == null) + if (localUserScores.Length == 0) preventTaggingReason = "Play the beatmap to contribute to beatmap tags!"; - else if (localUserScore.Ruleset.OnlineID != newScore.BeatmapInfo!.Ruleset.OnlineID) - preventTaggingReason = "Play the beatmap in its original ruleset to contribute to beatmap tags!"; - else if (localUserScore.Rank < ScoreRank.C) - preventTaggingReason = "Set a better score to contribute to beatmap tags!"; - else if (localUserScore.Mods.Any(m => (m.Type == ModType.Conversion) && !(m is ModClassic))) - preventTaggingReason = "Play this beatmap without conversion mods to contribute to beatmap tags!"; + else + { + foreach (ScoreInfo score in localUserScores) + { + // We may want to iterate on the following conditions further in the future + if (score.Ruleset.OnlineID != newScore.BeatmapInfo.Ruleset.OnlineID) + preventTaggingReason = "Play the beatmap in its original ruleset to contribute to beatmap tags!"; + else if (score.Rank < ScoreRank.C) + preventTaggingReason = "Set a better score to contribute to beatmap tags!"; + else if (score.Mods.Any(m => (m.Type == ModType.Conversion) && !(m is ModClassic))) + preventTaggingReason = "Play this beatmap without conversion mods to contribute to beatmap tags!"; + else + { + preventTaggingReason = null; + break; + } + } + } if (preventTaggingReason == null) {