mirror of
https://github.com/ppy/osu.git
synced 2024-12-13 05:22:54 +08:00
Move available mods to global context
This also tidies up ModSelectOverlay and setting creation flow in general.
This commit is contained in:
parent
fa7520d177
commit
440a8470e1
@ -83,6 +83,11 @@ namespace osu.Game
|
||||
[Cached(typeof(IBindable<IReadOnlyList<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
|
||||
|
||||
private Bindable<bool> fpsDisplayVisible;
|
||||
@ -233,6 +238,18 @@ namespace osu.Game
|
||||
PreviewTrackManager previewTrackManager;
|
||||
dependencies.Cache(previewTrackManager = new 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();
|
||||
|
@ -1,10 +1,10 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@ -12,14 +12,13 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
public class ModControlSection : Container
|
||||
public class ModControlSection : CompositeDrawable
|
||||
{
|
||||
protected FillFlowContainer FlowContent;
|
||||
protected override Container<Drawable> Content => FlowContent;
|
||||
|
||||
public readonly Mod Mod;
|
||||
|
||||
public ModControlSection(Mod mod)
|
||||
public ModControlSection(Mod mod, IEnumerable<Drawable> modControls)
|
||||
{
|
||||
Mod = mod;
|
||||
|
||||
@ -33,9 +32,8 @@ namespace osu.Game.Overlays.Mods
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
ChildrenEnumerable = modControls
|
||||
};
|
||||
|
||||
AddRange(Mod.CreateSettingsControls());
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -20,7 +20,6 @@ using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.Mods.Sections;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens;
|
||||
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 IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||
private Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods;
|
||||
|
||||
protected Color4 LowMultiplierColour;
|
||||
protected Color4 HighMultiplierColour;
|
||||
@ -322,14 +321,14 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
|
||||
[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;
|
||||
HighMultiplierColour = colours.Green;
|
||||
UnrankedLabel.Colour = colours.Blue;
|
||||
|
||||
Ruleset.BindTo(ruleset);
|
||||
if (mods != null) SelectedMods.BindTo(mods);
|
||||
availableMods = osu.AvailableMods.GetBoundCopy();
|
||||
SelectedMods.BindTo(selectedMods);
|
||||
|
||||
sampleOn = audio.Samples.Get(@"UI/check-on");
|
||||
sampleOff = audio.Samples.Get(@"UI/check-off");
|
||||
@ -360,7 +359,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Ruleset.BindValueChanged(rulesetChanged, true);
|
||||
availableMods.BindValueChanged(availableModsChanged, true);
|
||||
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
||||
}
|
||||
|
||||
@ -410,22 +409,12 @@ namespace osu.Game.Overlays.Mods
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
||||
private void availableModsChanged(ValueChangedEvent<Dictionary<ModType, IReadOnlyList<Mod>>> mods)
|
||||
{
|
||||
if (e.NewValue == null) return;
|
||||
|
||||
var instance = e.NewValue.CreateInstance();
|
||||
if (mods.NewValue == null) return;
|
||||
|
||||
foreach (var section in ModSectionsContainer.Children)
|
||||
section.Mods = instance.GetModsFor(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();
|
||||
section.Mods = mods.NewValue[section.ModType];
|
||||
}
|
||||
|
||||
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
@ -462,17 +451,17 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
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();
|
||||
if (controls.Count > 0)
|
||||
ModSettingsContent.Add(new ModControlSection(added) { Children = controls });
|
||||
var settings = mod.CreateSettingsControls().ToList();
|
||||
if (settings.Count > 0)
|
||||
ModSettingsContent.Add(new ModControlSection(mod, settings));
|
||||
}
|
||||
|
||||
foreach (var removed in selectedMods.OldValue.Except(selectedMods.NewValue))
|
||||
ModSettingsContent.RemoveAll(section => section.Mod == removed);
|
||||
bool hasSettings = ModSettingsContent.Count > 0;
|
||||
|
||||
bool hasSettings = ModSettingsContent.Children.Count > 0;
|
||||
CustomiseButton.Enabled.Value = hasSettings;
|
||||
|
||||
if (!hasSettings)
|
||||
@ -502,7 +491,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
Ruleset.UnbindAll();
|
||||
availableMods.UnbindAll();
|
||||
SelectedMods.UnbindAll();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user