mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 07:33:20 +08:00
Add ability to toggle all free mods quickly at multiplayer song select
This commit is contained in:
parent
88ac53557a
commit
eb149942e5
@ -67,6 +67,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen() && songSelect.BeatmapSetsLoaded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectFreeMods()
|
||||
{
|
||||
AddStep("set some freemods", () => songSelect.FreeMods.Value = new OsuRuleset().GetModsFor(ModType.Fun).ToArray());
|
||||
AddStep("set all freemods", () => songSelect.FreeMods.Value = new OsuRuleset().CreateAllMods().ToArray());
|
||||
AddStep("set no freemods", () => songSelect.FreeMods.Value = Array.Empty<Mod>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatmapConfirmed()
|
||||
{
|
||||
|
@ -111,6 +111,10 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> globalAvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||
|
||||
public IEnumerable<Mod> AllAvailableAndValidMods => allAvailableMods
|
||||
.Select(s => s.Mod)
|
||||
.Where(m => isValidMod(m));
|
||||
|
||||
private IEnumerable<ModState> allAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value);
|
||||
|
||||
private readonly BindableBool customisationVisible = new BindableBool();
|
||||
|
@ -1,15 +1,21 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Select;
|
||||
using osuTK;
|
||||
|
||||
@ -17,28 +23,60 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
{
|
||||
public partial class FooterButtonFreeMods : FooterButton, IHasCurrentValue<IReadOnlyList<Mod>>
|
||||
{
|
||||
public Bindable<IReadOnlyList<Mod>> Current
|
||||
public Bindable<IReadOnlyList<Mod>> Current { get; set; } = new BindableWithCurrent<IReadOnlyList<Mod>>();
|
||||
|
||||
private OsuSpriteText count = null!;
|
||||
|
||||
private Circle circle = null!;
|
||||
|
||||
private readonly FreeModSelectOverlay freeModSelectOverlay;
|
||||
|
||||
public FooterButtonFreeMods(FreeModSelectOverlay freeModSelectOverlay)
|
||||
{
|
||||
get => modDisplay.Current;
|
||||
set => modDisplay.Current = value;
|
||||
this.freeModSelectOverlay = freeModSelectOverlay;
|
||||
}
|
||||
|
||||
private readonly ModDisplay modDisplay;
|
||||
|
||||
public FooterButtonFreeMods()
|
||||
{
|
||||
ButtonContentContainer.Add(modDisplay = new ModDisplay
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(0.8f),
|
||||
ExpansionMode = ExpansionMode.AlwaysContracted,
|
||||
});
|
||||
}
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
private void load()
|
||||
{
|
||||
ButtonContentContainer.AddRange(new[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
circle = new Circle
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = colours.YellowDark,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
count = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Padding = new MarginPadding(5),
|
||||
UseFullGlyphHeight = false,
|
||||
}
|
||||
}
|
||||
},
|
||||
new IconButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(0.8f),
|
||||
Icon = FontAwesome.Solid.Bars,
|
||||
Action = () => freeModSelectOverlay.ToggleVisibility()
|
||||
}
|
||||
});
|
||||
|
||||
SelectedColour = colours.Yellow;
|
||||
DeselectedColour = SelectedColour.Opacity(0.5f);
|
||||
Text = @"freemods";
|
||||
@ -49,14 +87,42 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
base.LoadComplete();
|
||||
|
||||
Current.BindValueChanged(_ => updateModDisplay(), true);
|
||||
|
||||
// Overwrite any external behaviour as we delegate the main toggle action to a sub-button.
|
||||
Action = toggleAllFreeMods;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately toggle all free mods on/off.
|
||||
/// </summary>
|
||||
private void toggleAllFreeMods()
|
||||
{
|
||||
var availableMods = freeModSelectOverlay.AllAvailableAndValidMods.ToArray();
|
||||
|
||||
Current.Value = Current.Value.Count == availableMods.Length
|
||||
? Array.Empty<Mod>()
|
||||
: availableMods;
|
||||
}
|
||||
|
||||
private void updateModDisplay()
|
||||
{
|
||||
if (Current.Value?.Count > 0)
|
||||
modDisplay.FadeIn();
|
||||
int current = Current.Value.Count;
|
||||
|
||||
if (current == freeModSelectOverlay.AllAvailableAndValidMods.Count())
|
||||
{
|
||||
count.Text = "all";
|
||||
circle.FadeColour(colours.Yellow, 200, Easing.OutQuint);
|
||||
}
|
||||
else if (current > 0)
|
||||
{
|
||||
count.Text = $"{current} mods";
|
||||
circle.FadeColour(colours.YellowDark, 200, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
modDisplay.FadeOut();
|
||||
{
|
||||
count.Text = "off";
|
||||
circle.FadeColour(colours.Gray4, 200, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,9 +175,12 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
|
||||
protected override IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons()
|
||||
{
|
||||
var buttons = base.CreateFooterButtons().ToList();
|
||||
buttons.Insert(buttons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (new FooterButtonFreeMods { Current = FreeMods }, freeModSelectOverlay));
|
||||
return buttons;
|
||||
var baseButtons = base.CreateFooterButtons().ToList();
|
||||
var freeModsButton = new FooterButtonFreeMods(freeModSelectOverlay) { Current = FreeMods };
|
||||
|
||||
baseButtons.Insert(baseButtons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (freeModsButton, freeModSelectOverlay));
|
||||
|
||||
return baseButtons;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user