mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 16:59:53 +09:00
Expose available mod state outwardly as a bindable
This commit is contained in:
@ -34,6 +34,15 @@ namespace osu.Game.Overlays.Mods
|
|||||||
[Cached]
|
[Cached]
|
||||||
public Bindable<IReadOnlyList<Mod>> SelectedMods { get; private set; } = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
public Bindable<IReadOnlyList<Mod>> SelectedMods { 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>
|
||||||
|
/// <remarks>
|
||||||
|
/// Contrary to <see cref="OsuGameBase.AvailableMods"/> and <see cref="globalAvailableMods"/>, the <see cref="Mod"/> instances
|
||||||
|
/// inside the <see cref="ModState"/> objects are owned solely by this <see cref="ModSelectOverlay"/> instance.
|
||||||
|
/// </remarks>
|
||||||
|
public Bindable<Dictionary<ModType, IReadOnlyList<ModState>>> AvailableMods { get; } = new Bindable<Dictionary<ModType, IReadOnlyList<ModState>>>(new Dictionary<ModType, IReadOnlyList<ModState>>());
|
||||||
|
|
||||||
private Func<Mod, bool> isValidMod = m => true;
|
private Func<Mod, bool> isValidMod = m => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -79,9 +88,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
yield return new DeselectAllModsButton(this);
|
yield return new DeselectAllModsButton(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> globalAvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||||
private readonly Dictionary<ModType, IReadOnlyList<ModState>> localAvailableMods = new Dictionary<ModType, IReadOnlyList<ModState>>();
|
|
||||||
private IEnumerable<ModState> allLocalAvailableMods => localAvailableMods.SelectMany(pair => pair.Value);
|
private IEnumerable<ModState> allAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value);
|
||||||
|
|
||||||
private readonly BindableBool customisationVisible = new BindableBool();
|
private readonly BindableBool customisationVisible = new BindableBool();
|
||||||
|
|
||||||
@ -204,13 +213,13 @@ namespace osu.Game.Overlays.Mods
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
availableMods.BindTo(game.AvailableMods);
|
globalAvailableMods.BindTo(game.AvailableMods);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
// this is called before base call so that the mod state is populated early, and the transition in `PopIn()` can play out properly.
|
// this is called before base call so that the mod state is populated early, and the transition in `PopIn()` can play out properly.
|
||||||
availableMods.BindValueChanged(_ => createLocalMods(), true);
|
globalAvailableMods.BindValueChanged(_ => createLocalMods(), true);
|
||||||
|
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
@ -275,9 +284,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
private void createLocalMods()
|
private void createLocalMods()
|
||||||
{
|
{
|
||||||
localAvailableMods.Clear();
|
var newLocalAvailableMods = new Dictionary<ModType, IReadOnlyList<ModState>>();
|
||||||
|
|
||||||
foreach (var (modType, mods) in availableMods.Value)
|
foreach (var (modType, mods) in globalAvailableMods.Value)
|
||||||
{
|
{
|
||||||
var modStates = mods.SelectMany(ModUtils.FlattenMod)
|
var modStates = mods.SelectMany(ModUtils.FlattenMod)
|
||||||
.Select(mod => new ModState(mod.DeepClone()))
|
.Select(mod => new ModState(mod.DeepClone()))
|
||||||
@ -286,18 +295,19 @@ namespace osu.Game.Overlays.Mods
|
|||||||
foreach (var modState in modStates)
|
foreach (var modState in modStates)
|
||||||
modState.Active.BindValueChanged(_ => updateFromInternalSelection());
|
modState.Active.BindValueChanged(_ => updateFromInternalSelection());
|
||||||
|
|
||||||
localAvailableMods[modType] = modStates;
|
newLocalAvailableMods[modType] = modStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvailableMods.Value = newLocalAvailableMods;
|
||||||
filterMods();
|
filterMods();
|
||||||
|
|
||||||
foreach (var column in columnFlow.Columns)
|
foreach (var column in columnFlow.Columns)
|
||||||
column.AvailableMods = localAvailableMods.GetValueOrDefault(column.ModType, Array.Empty<ModState>());
|
column.AvailableMods = AvailableMods.Value.GetValueOrDefault(column.ModType, Array.Empty<ModState>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void filterMods()
|
private void filterMods()
|
||||||
{
|
{
|
||||||
foreach (var modState in allLocalAvailableMods)
|
foreach (var modState in allAvailableMods)
|
||||||
modState.Filtered.Value = !modState.Mod.HasImplementation || !IsValidMod.Invoke(modState.Mod);
|
modState.Filtered.Value = !modState.Mod.HasImplementation || !IsValidMod.Invoke(modState.Mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +388,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
var newSelection = new List<Mod>();
|
var newSelection = new List<Mod>();
|
||||||
|
|
||||||
foreach (var modState in allLocalAvailableMods)
|
foreach (var modState in allAvailableMods)
|
||||||
{
|
{
|
||||||
var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == modState.Mod.GetType());
|
var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == modState.Mod.GetType());
|
||||||
|
|
||||||
@ -405,9 +415,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
if (externalSelectionUpdateInProgress)
|
if (externalSelectionUpdateInProgress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var candidateSelection = allLocalAvailableMods.Where(modState => modState.Active.Value)
|
var candidateSelection = allAvailableMods.Where(modState => modState.Active.Value)
|
||||||
.Select(modState => modState.Mod)
|
.Select(modState => modState.Mod)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection);
|
SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user