Merge pull request #29163 from Joehuu/copy-lb-mods-daily

Add ability to copy leaderboard mods in daily challenge
This commit is contained in:
Bartłomiej Dach 2024-07-29 12:09:27 +02:00 committed by GitHub
commit cebd38c6eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 7 deletions

View File

@ -21,6 +21,7 @@ using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Online.API;
@ -169,7 +170,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
},
null,
[
new Container
new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
@ -239,6 +240,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
RelativeSizeAxes = Axes.Both,
PresentScore = presentScore,
SelectedMods = { BindTarget = userMods },
},
// Spacer
null,
@ -330,7 +332,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
var rulesetInstance = rulesets.GetRuleset(playlistItem.RulesetID)!.CreateInstance();
var allowedMods = playlistItem.AllowedMods.Select(m => m.ToMod(rulesetInstance));
userModsSelectOverlay.IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType());
userModsSelectOverlay.IsValidMod = leaderboard.IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType());
}
metadataClient.MultiplayerRoomScoreSet += onRoomScoreSet;

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
@ -14,6 +15,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.SelectV2.Leaderboards;
using osuTK;
@ -24,6 +26,14 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
public IBindable<MultiplayerScore?> UserBestScore => userBestScore;
private readonly Bindable<MultiplayerScore?> userBestScore = new Bindable<MultiplayerScore?>();
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>();
/// <summary>
/// A function determining whether each mod in the score can be selected.
/// A return value of <see langword="true"/> means that the mod can be selected in the current context.
/// A return value of <see langword="false"/> means that the mod cannot be selected in the current context.
/// </summary>
public Func<Mod, bool> IsValidMod { get; set; } = _ => true;
public Action<long>? PresentScore { get; init; }
@ -153,6 +163,8 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
Rank = index + 1,
IsPersonalBest = s.UserID == api.LocalUser.Value.Id,
Action = () => PresentScore?.Invoke(s.OnlineID),
SelectedMods = { BindTarget = SelectedMods },
IsValidMod = IsValidMod,
}), loaded =>
{
scoreFlow.Clear();
@ -171,6 +183,8 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
Rank = userBest.Position,
IsPersonalBest = true,
Action = () => PresentScore?.Invoke(userBest.OnlineID),
SelectedMods = { BindTarget = SelectedMods },
IsValidMod = IsValidMod,
});
}

View File

@ -43,6 +43,15 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
{
public partial class LeaderboardScoreV2 : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip<ScoreInfo>
{
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>();
/// <summary>
/// A function determining whether each mod in the score can be selected.
/// A return value of <see langword="true"/> means that the mod can be selected in the current context.
/// A return value of <see langword="false"/> means that the mod cannot be selected in the current context.
/// </summary>
public Func<Mod, bool> IsValidMod { get; set; } = _ => true;
public int? Rank { get; init; }
public bool IsPersonalBest { get; init; }
@ -68,9 +77,6 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
[Resolved]
private SongSelect? songSelect { get; set; }
[Resolved]
private IDialogOverlay? dialogOverlay { get; set; }
@ -738,8 +744,8 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
{
List<MenuItem> items = new List<MenuItem>();
if (score.Mods.Length > 0 && songSelect != null)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => songSelect.Mods.Value = score.Mods));
if (score.Mods.Length > 0)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => SelectedMods.Value = score.Mods.Where(m => IsValidMod.Invoke(m)).ToArray()));
if (score.Files.Count <= 0) return items.ToArray();

View File

@ -115,6 +115,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay
MaxCombo = 1000,
TotalScore = 1000000,
User = new APIUser { Username = "best user" },
Mods = [new APIMod { Acronym = @"DT" }],
Statistics = new Dictionary<HitResult, int>()
},
new MultiplayerScore