1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:07:25 +08:00

Introduce the concept of ActiveMods in mod select overlay and rewrite once more

This commit is contained in:
Salman Ahmed 2024-02-26 22:25:04 +03:00
parent 2b73d816a7
commit 3f9fbb9318
2 changed files with 32 additions and 26 deletions

View File

@ -42,6 +42,14 @@ namespace osu.Game.Overlays.Mods
[Cached]
public Bindable<IReadOnlyList<Mod>> SelectedMods { get; private set; } = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
/// <summary>
/// Contains a list of mods which <see cref="ModSelectOverlay"/> should read from to display effects on the selected beatmap.
/// </summary>
/// <remarks>
/// This is different from <see cref="SelectedMods"/> in screens like online-play rooms, where there are required mods activated from the playlist.
/// </remarks>
public Bindable<IReadOnlyList<Mod>> ActiveMods { get; private set; } = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
/// <summary>
/// Contains a dictionary with the current <see cref="ModState"/> of all mods applicable for the current ruleset.
/// </summary>
@ -313,22 +321,29 @@ namespace osu.Game.Overlays.Mods
if (AllowCustomisation)
((IBindable<IReadOnlyList<Mod>>)modSettingsArea.SelectedMods).BindTo(SelectedMods);
SelectedMods.BindValueChanged(_ =>
SelectedMods.BindValueChanged(mods =>
{
UpdateOverlayInformation(SelectedMods.Value);
var newMods = ActiveMods.Value.Except(mods.OldValue).Concat(mods.NewValue).ToList();
ActiveMods.Value = newMods;
updateFromExternalSelection();
updateCustomisation();
}, true);
ActiveMods.BindValueChanged(_ =>
{
updateOverlayInformation();
modSettingChangeTracker?.Dispose();
if (AllowCustomisation)
{
// Importantly, use SelectedMods.Value here (and not the ValueChanged NewValue) as the latter can
// Importantly, use ActiveMods.Value here (and not the ValueChanged NewValue) as the latter can
// potentially be stale, due to complexities in the way change trackers work.
//
// See https://github.com/ppy/osu/pull/23284#issuecomment-1529056988
modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value);
modSettingChangeTracker.SettingChanged += _ => UpdateOverlayInformation(SelectedMods.Value);
modSettingChangeTracker = new ModSettingChangeTracker(ActiveMods.Value);
modSettingChangeTracker.SettingChanged += _ => updateOverlayInformation();
}
}, true);
@ -451,24 +466,24 @@ namespace osu.Game.Overlays.Mods
}
/// <summary>
/// Updates any information displayed on the overlay regarding the effects of the selected mods.
/// Updates any information displayed on the overlay regarding the effects of the active mods.
/// This reads from <see cref="ActiveMods"/> instead of <see cref="SelectedMods"/>.
/// </summary>
/// <param name="mods">The list of mods to show effect from. This can be overriden to include effect of mods that are not part of the <see cref="SelectedMods"/> bindable (e.g. room mods in multiplayer/playlists).</param>
protected virtual void UpdateOverlayInformation(IReadOnlyList<Mod> mods)
private void updateOverlayInformation()
{
if (rankingInformationDisplay != null)
{
double multiplier = 1.0;
foreach (var mod in mods)
foreach (var mod in ActiveMods.Value)
multiplier *= mod.ScoreMultiplier;
rankingInformationDisplay.ModMultiplier.Value = multiplier;
rankingInformationDisplay.Ranked.Value = mods.All(m => m.Ranked);
rankingInformationDisplay.Ranked.Value = ActiveMods.Value.All(m => m.Ranked);
}
if (beatmapAttributesDisplay != null)
beatmapAttributesDisplay.Mods.Value = mods;
beatmapAttributesDisplay.Mods.Value = ActiveMods.Value;
}
private void updateCustomisation()

View File

@ -1,7 +1,6 @@
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
@ -10,7 +9,6 @@ using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Screens.OnlinePlay.Match
{
@ -22,8 +20,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
[Resolved]
private RulesetStore rulesets { get; set; } = null!;
private readonly List<Mod> roomMods = new List<Mod>();
public RoomModSelectOverlay()
: base(OverlayColourScheme.Plum)
{
@ -33,22 +29,17 @@ namespace osu.Game.Screens.OnlinePlay.Match
{
base.LoadComplete();
selectedItem.BindValueChanged(_ =>
selectedItem.BindValueChanged(v =>
{
roomMods.Clear();
if (selectedItem.Value is PlaylistItem item)
if (v.NewValue is PlaylistItem item)
{
var rulesetInstance = rulesets.GetRuleset(item.RulesetID)?.CreateInstance();
Debug.Assert(rulesetInstance != null);
roomMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
ActiveMods.Value = item.RequiredMods.Select(m => m.ToMod(rulesetInstance)).Concat(SelectedMods.Value).ToList();
}
SelectedMods.TriggerChange();
});
else
ActiveMods.Value = SelectedMods.Value;
}, true);
}
protected override void UpdateOverlayInformation(IReadOnlyList<Mod> mods)
=> base.UpdateOverlayInformation(roomMods.Concat(mods).ToList());
}
}