1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 06:47:24 +08:00

Add ability to copy leaderboard mods in daily challenge

This commit is contained in:
Joseph Madamba 2024-07-27 23:50:52 -07:00
parent 565107205c
commit f6eb9037df
3 changed files with 41 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;
@ -168,7 +169,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
},
null,
[
new Container
new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
@ -238,6 +239,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
RelativeSizeAxes = Axes.Both,
PresentScore = presentScore,
SelectedMods = { BindTarget = userMods },
},
// Spacer
null,
@ -329,7 +331,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,20 @@ 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>>();
private Func<Mod, bool> isValidMod = _ => true;
/// <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 => isValidMod;
set => isValidMod = value ?? throw new ArgumentNullException(nameof(value));
}
public Action<long>? PresentScore { get; init; }
@ -153,6 +169,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 +189,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,21 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
{
public partial class LeaderboardScoreV2 : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip<ScoreInfo>
{
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>();
private Func<Mod, bool> isValidMod = _ => true;
/// <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 => isValidMod;
set => isValidMod = value ?? throw new ArgumentNullException(nameof(value));
}
public int? Rank { get; init; }
public bool IsPersonalBest { get; init; }
@ -68,9 +83,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 +750,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();