1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

Move available mods to global context

This also tidies up ModSelectOverlay and setting creation flow in general.
This commit is contained in:
Dean Herbert 2019-12-12 18:53:25 +09:00
parent fa7520d177
commit 440a8470e1
3 changed files with 37 additions and 33 deletions

View File

@ -83,6 +83,11 @@ namespace osu.Game
[Cached(typeof(IBindable<IReadOnlyList<Mod>>))] [Cached(typeof(IBindable<IReadOnlyList<Mod>>))]
protected readonly Bindable<IReadOnlyList<Mod>> Mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>()); protected readonly Bindable<IReadOnlyList<Mod>> Mods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
/// <summary>
/// Mods available for the current <see cref="Ruleset"/>.
/// </summary>
public readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> AvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method
private Bindable<bool> fpsDisplayVisible; private Bindable<bool> fpsDisplayVisible;
@ -233,6 +238,18 @@ namespace osu.Game
PreviewTrackManager previewTrackManager; PreviewTrackManager previewTrackManager;
dependencies.Cache(previewTrackManager = new PreviewTrackManager()); dependencies.Cache(previewTrackManager = new PreviewTrackManager());
Add(previewTrackManager); Add(previewTrackManager);
Ruleset.BindValueChanged(onRulesetChanged);
}
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
{
var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();
foreach (ModType type in Enum.GetValues(typeof(ModType))) dict[type] = r.NewValue?.CreateInstance().GetModsFor(type).ToList();
SelectedMods.Value = Array.Empty<Mod>();
AvailableMods.Value = dict;
} }
protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer(); protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();

View File

@ -1,10 +1,10 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -12,14 +12,13 @@ using osuTK;
namespace osu.Game.Overlays.Mods namespace osu.Game.Overlays.Mods
{ {
public class ModControlSection : Container public class ModControlSection : CompositeDrawable
{ {
protected FillFlowContainer FlowContent; protected FillFlowContainer FlowContent;
protected override Container<Drawable> Content => FlowContent;
public readonly Mod Mod; public readonly Mod Mod;
public ModControlSection(Mod mod) public ModControlSection(Mod mod, IEnumerable<Drawable> modControls)
{ {
Mod = mod; Mod = mod;
@ -33,9 +32,8 @@ namespace osu.Game.Overlays.Mods
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
ChildrenEnumerable = modControls
}; };
AddRange(Mod.CreateSettingsControls());
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -20,7 +20,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods.Sections; using osu.Game.Overlays.Mods.Sections;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Screens; using osu.Game.Screens;
using osuTK; using osuTK;
@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Mods
protected readonly Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>()); protected readonly Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>(); private Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods;
protected Color4 LowMultiplierColour; protected Color4 LowMultiplierColour;
protected Color4 HighMultiplierColour; protected Color4 HighMultiplierColour;
@ -322,14 +321,14 @@ namespace osu.Game.Overlays.Mods
} }
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods) private void load(OsuColour colours, AudioManager audio, Bindable<IReadOnlyList<Mod>> selectedMods, OsuGameBase osu)
{ {
LowMultiplierColour = colours.Red; LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green; HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue; UnrankedLabel.Colour = colours.Blue;
Ruleset.BindTo(ruleset); availableMods = osu.AvailableMods.GetBoundCopy();
if (mods != null) SelectedMods.BindTo(mods); SelectedMods.BindTo(selectedMods);
sampleOn = audio.Samples.Get(@"UI/check-on"); sampleOn = audio.Samples.Get(@"UI/check-on");
sampleOff = audio.Samples.Get(@"UI/check-off"); sampleOff = audio.Samples.Get(@"UI/check-off");
@ -360,7 +359,7 @@ namespace osu.Game.Overlays.Mods
{ {
base.LoadComplete(); base.LoadComplete();
Ruleset.BindValueChanged(rulesetChanged, true); availableMods.BindValueChanged(availableModsChanged, true);
SelectedMods.BindValueChanged(selectedModsChanged, true); SelectedMods.BindValueChanged(selectedModsChanged, true);
} }
@ -410,22 +409,12 @@ namespace osu.Game.Overlays.Mods
return base.OnKeyDown(e); return base.OnKeyDown(e);
} }
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e) private void availableModsChanged(ValueChangedEvent<Dictionary<ModType, IReadOnlyList<Mod>>> mods)
{ {
if (e.NewValue == null) return; if (mods.NewValue == null) return;
var instance = e.NewValue.CreateInstance();
foreach (var section in ModSectionsContainer.Children) foreach (var section in ModSectionsContainer.Children)
section.Mods = instance.GetModsFor(section.ModType); section.Mods = mods.NewValue[section.ModType];
// attempt to re-select any already selected mods.
// this may be the first time we are receiving the ruleset, in which case they will still match.
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
// this generally isn't required as the previous line will perform deselection; just here for safety.
refreshSelectedMods();
} }
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods) private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
@ -462,17 +451,17 @@ namespace osu.Game.Overlays.Mods
private void updateModSettings(ValueChangedEvent<IReadOnlyList<Mod>> selectedMods) private void updateModSettings(ValueChangedEvent<IReadOnlyList<Mod>> selectedMods)
{ {
foreach (var added in selectedMods.NewValue.Except(selectedMods.OldValue)) ModSettingsContent.Clear();
foreach (var mod in selectedMods.NewValue)
{ {
var controls = added.CreateSettingsControls().ToList(); var settings = mod.CreateSettingsControls().ToList();
if (controls.Count > 0) if (settings.Count > 0)
ModSettingsContent.Add(new ModControlSection(added) { Children = controls }); ModSettingsContent.Add(new ModControlSection(mod, settings));
} }
foreach (var removed in selectedMods.OldValue.Except(selectedMods.NewValue)) bool hasSettings = ModSettingsContent.Count > 0;
ModSettingsContent.RemoveAll(section => section.Mod == removed);
bool hasSettings = ModSettingsContent.Children.Count > 0;
CustomiseButton.Enabled.Value = hasSettings; CustomiseButton.Enabled.Value = hasSettings;
if (!hasSettings) if (!hasSettings)
@ -502,7 +491,7 @@ namespace osu.Game.Overlays.Mods
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
Ruleset.UnbindAll(); availableMods.UnbindAll();
SelectedMods.UnbindAll(); SelectedMods.UnbindAll();
} }