mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 18:12:56 +08:00
Allow unstacking mods
This commit is contained in:
parent
230b347c1e
commit
797a810287
@ -22,6 +22,7 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
|
using osu.Game.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -46,9 +47,27 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected readonly ModSettingsContainer ModSettingsContainer;
|
protected readonly ModSettingsContainer ModSettingsContainer;
|
||||||
|
|
||||||
|
private bool stacked = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether mod icons should be stacked, or appear as individual buttons.
|
||||||
|
/// </summary>
|
||||||
|
public bool Stacked
|
||||||
|
{
|
||||||
|
get => stacked;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
stacked = value;
|
||||||
|
updateAvailableMods();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NotNull]
|
[NotNull]
|
||||||
private Func<Mod, bool> isValidMod = m => true;
|
private Func<Mod, bool> isValidMod = m => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A function that checks whether a given mod is valid.
|
||||||
|
/// </summary>
|
||||||
[NotNull]
|
[NotNull]
|
||||||
public Func<Mod, bool> IsValidMod
|
public Func<Mod, bool> IsValidMod
|
||||||
{
|
{
|
||||||
@ -419,11 +438,18 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
private void updateAvailableMods()
|
private void updateAvailableMods()
|
||||||
{
|
{
|
||||||
if (availableMods.Value == null)
|
if (availableMods?.Value == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var section in ModSectionsContainer.Children)
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
section.Mods = availableMods.Value[section.ModType].Where(IsValidMod);
|
{
|
||||||
|
IEnumerable<Mod> modEnumeration = availableMods.Value[section.ModType];
|
||||||
|
|
||||||
|
if (!stacked)
|
||||||
|
modEnumeration = ModValidation.FlattenMods(modEnumeration);
|
||||||
|
|
||||||
|
section.Mods = modEnumeration.Where(IsValidMod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||||
|
@ -14,6 +14,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
public class FreeModSelectOverlay : ModSelectOverlay
|
public class FreeModSelectOverlay : ModSelectOverlay
|
||||||
{
|
{
|
||||||
|
public FreeModSelectOverlay()
|
||||||
|
{
|
||||||
|
Stacked = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected override ModSection CreateModSection(ModType type) => new FreeModSection(type);
|
protected override ModSection CreateModSection(ModType type) => new FreeModSection(type);
|
||||||
|
|
||||||
private class FreeModSection : ModSection
|
private class FreeModSection : ModSection
|
||||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Utils
|
|||||||
var incompatibleTypes = new HashSet<Type>();
|
var incompatibleTypes = new HashSet<Type>();
|
||||||
var incomingTypes = new HashSet<Type>();
|
var incomingTypes = new HashSet<Type>();
|
||||||
|
|
||||||
foreach (var mod in combination.SelectMany(flattenMod))
|
foreach (var mod in combination.SelectMany(FlattenMod))
|
||||||
{
|
{
|
||||||
// Add the new mod incompatibilities, checking whether any match the existing mod types.
|
// Add the new mod incompatibilities, checking whether any match the existing mod types.
|
||||||
foreach (var t in mod.IncompatibleMods)
|
foreach (var t in mod.IncompatibleMods)
|
||||||
@ -79,7 +79,7 @@ namespace osu.Game.Utils
|
|||||||
{
|
{
|
||||||
var allowedSet = new HashSet<Type>(allowedTypes);
|
var allowedSet = new HashSet<Type>(allowedTypes);
|
||||||
|
|
||||||
return combination.SelectMany(flattenMod)
|
return combination.SelectMany(FlattenMod)
|
||||||
.All(m => allowedSet.Contains(m.GetType()));
|
.All(m => allowedSet.Contains(m.GetType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,20 +93,27 @@ namespace osu.Game.Utils
|
|||||||
/// <param name="incompatibleTypes">The set of incompatible <see cref="Mod"/> types.</param>
|
/// <param name="incompatibleTypes">The set of incompatible <see cref="Mod"/> types.</param>
|
||||||
/// <returns>Whether the given <see cref="Mod"/> is incompatible.</returns>
|
/// <returns>Whether the given <see cref="Mod"/> is incompatible.</returns>
|
||||||
private static bool isModIncompatible(Mod mod, ICollection<Type> incompatibleTypes)
|
private static bool isModIncompatible(Mod mod, ICollection<Type> incompatibleTypes)
|
||||||
=> flattenMod(mod)
|
=> FlattenMod(mod)
|
||||||
.SelectMany(m => m.GetType().EnumerateBaseTypes())
|
.SelectMany(m => m.GetType().EnumerateBaseTypes())
|
||||||
.Any(incompatibleTypes.Contains);
|
.Any(incompatibleTypes.Contains);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flattens a set of <see cref="Mod"/>s, returning a new set with all <see cref="MultiMod"/>s removed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mods">The set of <see cref="Mod"/>s to flatten.</param>
|
||||||
|
/// <returns>The new set, containing all <see cref="Mod"/>s in <paramref name="mods"/> recursively with all <see cref="MultiMod"/>s removed.</returns>
|
||||||
|
public static IEnumerable<Mod> FlattenMods(IEnumerable<Mod> mods) => mods.SelectMany(FlattenMod);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Flattens a <see cref="Mod"/>, returning a set of <see cref="Mod"/>s in-place of any <see cref="MultiMod"/>s.
|
/// Flattens a <see cref="Mod"/>, returning a set of <see cref="Mod"/>s in-place of any <see cref="MultiMod"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mod">The <see cref="Mod"/> to flatten.</param>
|
/// <param name="mod">The <see cref="Mod"/> to flatten.</param>
|
||||||
/// <returns>A set of singular "flattened" <see cref="Mod"/>s</returns>
|
/// <returns>A set of singular "flattened" <see cref="Mod"/>s</returns>
|
||||||
private static IEnumerable<Mod> flattenMod(Mod mod)
|
public static IEnumerable<Mod> FlattenMod(Mod mod)
|
||||||
{
|
{
|
||||||
if (mod is MultiMod multi)
|
if (mod is MultiMod multi)
|
||||||
{
|
{
|
||||||
foreach (var m in multi.Mods.SelectMany(flattenMod))
|
foreach (var m in multi.Mods.SelectMany(FlattenMod))
|
||||||
yield return m;
|
yield return m;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user