1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:57:36 +08:00

Remember mod selection when re-entering song select

Removes mod application when exiting back to main menu.

Alternative to #1968.
Closes #1961.
This commit is contained in:
Dean Herbert 2018-01-26 19:30:29 +09:00
parent 545a4bd082
commit 7852015db3
5 changed files with 74 additions and 32 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System;
using System.Collections.Generic;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -27,6 +28,7 @@ using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Mods;
using OpenTK.Graphics; using OpenTK.Graphics;
namespace osu.Game namespace osu.Game
@ -80,6 +82,9 @@ namespace osu.Game
private SettingsOverlay settings; private SettingsOverlay settings;
// todo: move this to SongSelect once Screen has the ability to unsuspend.
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
public OsuGame(string[] args = null) public OsuGame(string[] args = null)
{ {
this.args = args; this.args = args;

View File

@ -188,17 +188,19 @@ namespace osu.Game.Overlays.Mods
start = Mods.Length - 1; start = Mods.Length - 1;
for (int i = start; i < Mods.Length && i >= 0; i += direction) for (int i = start; i < Mods.Length && i >= 0; i += direction)
{ if (SelectAt(i)) return;
if (Mods[i].HasImplementation)
{
changeSelectedIndex(i);
return;
}
}
Deselect(); Deselect();
} }
public bool SelectAt(int index)
{
if (!Mods[index].HasImplementation) return false;
changeSelectedIndex(index);
return true;
}
public void Deselect() => changeSelectedIndex(-1); public void Deselect() => changeSelectedIndex(-1);
private void displayMod(Mod mod) private void displayMod(Mod mod)

View File

@ -113,6 +113,23 @@ namespace osu.Game.Overlays.Mods
} }
} }
/// <summary>
/// Select one or more mods in this section.
/// </summary>
/// <param name="mods">The types of <see cref="Mod"/>s which should be deselected.</param>
public void SelectTypes(IEnumerable<Mod> mods)
{
foreach (var button in buttons)
{
for (int i = 0; i < button.Mods.Length; i++)
{
foreach (var mod in mods)
if (mod.GetType().IsInstanceOfType(button.Mods[i]))
button.SelectAt(i);
}
}
}
protected ModSection() protected ModSection()
{ {
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;

View File

@ -51,6 +51,8 @@ namespace osu.Game.Overlays.Mods
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets) private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets)
{ {
SelectedMods.ValueChanged += selectedModsChanged;
LowMultiplierColour = colours.Red; LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green; HighMultiplierColour = colours.Green;
@ -63,6 +65,37 @@ namespace osu.Game.Overlays.Mods
Ruleset.TriggerChange(); Ruleset.TriggerChange();
} }
private void selectedModsChanged(IEnumerable<Mod> obj)
{
foreach (ModSection section in ModSectionsContainer.Children)
section.SelectTypes(obj);
updateMods();
}
private void updateMods()
{
double multiplier = 1.0;
bool ranked = true;
foreach (Mod mod in SelectedMods.Value)
{
multiplier *= mod.ScoreMultiplier;
ranked &= mod.Ranked;
}
MultiplierLabel.Text = $"{multiplier:N2}x";
if (!ranked)
MultiplierLabel.Text += " (Unranked)";
if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else
MultiplierLabel.FadeColour(Color4.White, 200);
}
protected override void PopOut() protected override void PopOut()
{ {
base.PopOut(); base.PopOut();
@ -97,6 +130,7 @@ namespace osu.Game.Overlays.Mods
{ {
foreach (ModSection section in ModSectionsContainer.Children) foreach (ModSection section in ModSectionsContainer.Children)
section.DeselectAll(); section.DeselectAll();
refreshSelectedMods(); refreshSelectedMods();
} }
@ -119,30 +153,7 @@ namespace osu.Game.Overlays.Mods
refreshSelectedMods(); refreshSelectedMods();
} }
private void refreshSelectedMods() private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
{
SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
double multiplier = 1.0;
bool ranked = true;
foreach (Mod mod in SelectedMods.Value)
{
multiplier *= mod.ScoreMultiplier;
ranked &= mod.Ranked;
}
MultiplierLabel.Text = $"{multiplier:N2}x";
if (!ranked)
MultiplierLabel.Text += " (Unranked)";
if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else
MultiplierLabel.FadeColour(Color4.White, 200);
}
public ModSelectOverlay() public ModSelectOverlay()
{ {

View File

@ -13,6 +13,7 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking; using osu.Game.Screens.Ranking;
@ -47,10 +48,13 @@ namespace osu.Game.Screens.Select
private SampleChannel sampleConfirm; private SampleChannel sampleConfirm;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay) private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame game)
{ {
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
if (game != null)
modSelect.SelectedMods.BindTo(game.SelectedMods);
Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue); Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue);
BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
@ -121,6 +125,9 @@ namespace osu.Game.Screens.Select
if (Beatmap.Value.Track != null) if (Beatmap.Value.Track != null)
Beatmap.Value.Track.Looping = false; Beatmap.Value.Track.Looping = false;
Beatmap.Value.Mods.UnbindBindings();
Beatmap.Value.Mods.Value = new Mod[] { };
return false; return false;
} }