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:
parent
fa7520d177
commit
440a8470e1
@ -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();
|
||||||
|
@ -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]
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user