1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 20:22:55 +08:00

Merge branch 'master' into judgement-rework

This commit is contained in:
Dean Herbert 2018-08-14 13:16:16 +09:00 committed by GitHub
commit 270dc2d1be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 211 additions and 139 deletions

View File

@ -14,24 +14,20 @@ namespace osu.Game.Rulesets.Mania.Tests
/// </summary> /// </summary>
public class ScrollingTestContainer : Container public class ScrollingTestContainer : Container
{ {
private readonly ScrollingDirection direction; [Cached(Type = typeof(IScrollingInfo))]
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
public ScrollingTestContainer(ScrollingDirection direction) public ScrollingTestContainer(ScrollingDirection direction)
{ {
this.direction = direction; scrollingInfo.Direction.Value = direction;
} }
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up;
{ }
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IScrollingInfo>(new ScrollingInfo { Direction = { Value = direction }});
return dependencies;
}
private class ScrollingInfo : IScrollingInfo public class TestScrollingInfo : IScrollingInfo
{ {
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction; IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
}
} }
} }

View File

@ -46,15 +46,20 @@ namespace osu.Game.Rulesets.Mania.Tests
Spacing = new Vector2(20), Spacing = new Vector2(20),
Children = new[] Children = new[]
{ {
createNoteDisplay(ScrollingDirection.Down), createNoteDisplay(ScrollingDirection.Down, 1, out var note1),
createNoteDisplay(ScrollingDirection.Up), createNoteDisplay(ScrollingDirection.Up, 2, out var note2),
createHoldNoteDisplay(ScrollingDirection.Down), createHoldNoteDisplay(ScrollingDirection.Down, 1, out var holdNote1),
createHoldNoteDisplay(ScrollingDirection.Up), createHoldNoteDisplay(ScrollingDirection.Up, 2, out var holdNote2),
} }
}; };
AddAssert("note 1 facing downwards", () => verifyAnchors(note1, Anchor.y2));
AddAssert("note 2 facing upwards", () => verifyAnchors(note2, Anchor.y0));
AddAssert("hold note 1 facing downwards", () => verifyAnchors(holdNote1, Anchor.y2));
AddAssert("hold note 2 facing upwards", () => verifyAnchors(holdNote2, Anchor.y0));
} }
private Drawable createNoteDisplay(ScrollingDirection direction) private Drawable createNoteDisplay(ScrollingDirection direction, int identifier, out DrawableNote hitObject)
{ {
var note = new Note { StartTime = 999999999 }; var note = new Note { StartTime = 999999999 };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
@ -62,24 +67,24 @@ namespace osu.Game.Rulesets.Mania.Tests
return new ScrollingTestContainer(direction) return new ScrollingTestContainer(direction)
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLowerInvariant()}") Child = new NoteContainer(direction, $"note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}")
{ {
Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed } Child = hitObject = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
} }
}; };
} }
private Drawable createHoldNoteDisplay(ScrollingDirection direction) private Drawable createHoldNoteDisplay(ScrollingDirection direction, int identifier, out DrawableHoldNote hitObject)
{ {
var note = new HoldNote { StartTime = 999999999, Duration = 1000 }; var note = new HoldNote { StartTime = 999999999, Duration = 5000 };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
return new ScrollingTestContainer(direction) return new ScrollingTestContainer(direction)
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLowerInvariant()}") Child = new NoteContainer(direction, $"hold note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}")
{ {
Child = new DrawableHoldNote(note) Child = hitObject = new DrawableHoldNote(note)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
AccentColour = Color4.OrangeRed, AccentColour = Color4.OrangeRed,
@ -88,6 +93,12 @@ namespace osu.Game.Rulesets.Mania.Tests
}; };
} }
private bool verifyAnchors(DrawableHitObject hitObject, Anchor expectedAnchor)
=> hitObject.Anchor.HasFlag(expectedAnchor) && hitObject.Origin.HasFlag(expectedAnchor);
private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor)
=> verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor));
private class NoteContainer : Container private class NoteContainer : Container
{ {
private readonly Container content; private readonly Container content;

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.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -24,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Tests
private readonly List<ManiaStage> stages = new List<ManiaStage>(); private readonly List<ManiaStage> stages = new List<ManiaStage>();
private FillFlowContainer<ScrollingTestContainer> fill;
public TestCaseStage() public TestCaseStage()
: base(columns) : base(columns)
{ {
@ -32,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Tests
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Child = new FillFlowContainer Child = fill = new FillFlowContainer<ScrollingTestContainer>
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
@ -54,8 +57,22 @@ namespace osu.Game.Rulesets.Mania.Tests
AddStep("hold note", createHoldNote); AddStep("hold note", createHoldNote);
AddStep("minor bar line", () => createBarLine(false)); AddStep("minor bar line", () => createBarLine(false));
AddStep("major bar line", () => createBarLine(true)); AddStep("major bar line", () => createBarLine(true));
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.TopCentre));
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.BottomCentre));
AddStep("flip direction", () =>
{
foreach (var c in fill.Children)
c.Flip();
});
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.BottomCentre));
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.TopCentre));
} }
private bool notesInStageAreAnchored(ManiaStage stage, Anchor anchor) => stage.Columns.SelectMany(c => c.AllHitObjects).All(o => o.Anchor == anchor);
private void createNote() private void createNote()
{ {
foreach (var stage in stages) foreach (var stage in stages)
@ -101,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Tests
} }
} }
private Drawable createStage(ScrollingDirection direction, ManiaAction action) private ScrollingTestContainer createStage(ScrollingDirection direction, ManiaAction action)
{ {
var specialAction = ManiaAction.Special1; var specialAction = ManiaAction.Special1;

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI
public ManiaScrollingInfo(ManiaConfigManager config) public ManiaScrollingInfo(ManiaConfigManager config)
{ {
config.BindWith(ManiaSetting.ScrollDirection, configDirection); config.BindWith(ManiaSetting.ScrollDirection, configDirection);
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v); configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
} }
} }
} }

View File

@ -2,7 +2,6 @@
// 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.ComponentModel;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
@ -13,11 +12,11 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Rulesets.Osu; using NUnit.Framework;
using osu.Framework.Configuration;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Overlays.Mods.Sections; using osu.Game.Overlays.Mods.Sections;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -50,11 +49,6 @@ namespace osu.Game.Tests.Visual
private void load(RulesetStore rulesets) private void load(RulesetStore rulesets)
{ {
this.rulesets = rulesets; this.rulesets = rulesets;
}
protected override void LoadComplete()
{
base.LoadComplete();
Add(modSelect = new TestModSelectOverlay Add(modSelect = new TestModSelectOverlay
{ {
@ -71,34 +65,25 @@ namespace osu.Game.Tests.Visual
Position = new Vector2(0, 25), Position = new Vector2(0, 25),
}); });
modDisplay.Current.UnbindBindings();
modDisplay.Current.BindTo(modSelect.SelectedMods); modDisplay.Current.BindTo(modSelect.SelectedMods);
AddStep("Toggle", modSelect.ToggleVisibility);
AddStep("Hide", modSelect.Hide);
AddStep("Show", modSelect.Show); AddStep("Show", modSelect.Show);
AddStep("Toggle", modSelect.ToggleVisibility);
foreach (var rulesetInfo in rulesets.AvailableRulesets) AddStep("Toggle", modSelect.ToggleVisibility);
{
Ruleset ruleset = rulesetInfo.CreateInstance();
AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo);
switch (ruleset)
{
case OsuRuleset or:
testOsuMods(or);
break;
case ManiaRuleset mr:
testManiaMods(mr);
break;
}
}
} }
private void testOsuMods(OsuRuleset ruleset) [Test]
public void TestOsuMods()
{ {
var easierMods = ruleset.GetModsFor(ModType.DifficultyReduction); var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 0);
var harderMods = ruleset.GetModsFor(ModType.DifficultyIncrease); AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
var assistMods = ruleset.GetModsFor(ModType.Automation);
var instance = ruleset.CreateInstance();
var easierMods = instance.GetModsFor(ModType.DifficultyReduction);
var harderMods = instance.GetModsFor(ModType.DifficultyIncrease);
var assistMods = instance.GetModsFor(ModType.Automation);
var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail);
var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden);
@ -120,9 +105,40 @@ namespace osu.Game.Tests.Visual
testUnimplementedMod(autoPilotMod); testUnimplementedMod(autoPilotMod);
} }
private void testManiaMods(ManiaRuleset ruleset) [Test]
public void TestManiaMods()
{ {
testRankedText(ruleset.GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom)); var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 3);
AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
testRankedText(ruleset.CreateInstance().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom));
}
[Test]
public void TestRulesetChanges()
{
var rulesetOsu = rulesets.AvailableRulesets.First(r => r.ID == 0);
var rulesetMania = rulesets.AvailableRulesets.First(r => r.ID == 3);
AddStep("change ruleset to null", () => { Ruleset.Value = null; });
var instance = rulesetOsu.CreateInstance();
var easierMods = instance.GetModsFor(ModType.DifficultyReduction);
var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail);
AddStep("set mods externally", () => { modDisplay.Current.Value = new[] { noFailMod }; });
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
AddAssert("ensure mods still selected", () => modDisplay.Current.Value.Single(m => m is OsuModNoFail) != null);
AddStep("change ruleset to mania", () => { Ruleset.Value = rulesetMania; });
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any(m => m is OsuModNoFail));
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any());
} }
private void testSingleMod(Mod mod) private void testSingleMod(Mod mod)
@ -237,6 +253,8 @@ namespace osu.Game.Tests.Visual
private class TestModSelectOverlay : ModSelectOverlay private class TestModSelectOverlay : ModSelectOverlay
{ {
public new Bindable<IEnumerable<Mod>> SelectedMods => base.SelectedMods;
public ModButton GetModButton(Mod mod) public ModButton GetModButton(Mod mod)
{ {
var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type); var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type);

View File

@ -354,6 +354,11 @@ namespace osu.Game.Beatmaps.Formats
private void handleTimingControlPoint(TimingControlPoint newPoint) private void handleTimingControlPoint(TimingControlPoint newPoint)
{ {
var existing = beatmap.ControlPointInfo.TimingPointAt(newPoint.Time);
if (existing.Time == newPoint.Time)
beatmap.ControlPointInfo.TimingPoints.Remove(existing);
beatmap.ControlPointInfo.TimingPoints.Add(newPoint); beatmap.ControlPointInfo.TimingPoints.Add(newPoint);
} }
@ -364,7 +369,9 @@ namespace osu.Game.Beatmaps.Formats
if (newPoint.EquivalentTo(existing)) if (newPoint.EquivalentTo(existing))
return; return;
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time); if (existing.Time == newPoint.Time)
beatmap.ControlPointInfo.DifficultyPoints.Remove(existing);
beatmap.ControlPointInfo.DifficultyPoints.Add(newPoint); beatmap.ControlPointInfo.DifficultyPoints.Add(newPoint);
} }
@ -375,6 +382,9 @@ namespace osu.Game.Beatmaps.Formats
if (newPoint.EquivalentTo(existing)) if (newPoint.EquivalentTo(existing))
return; return;
if (existing.Time == newPoint.Time)
beatmap.ControlPointInfo.EffectPoints.Remove(existing);
beatmap.ControlPointInfo.EffectPoints.Add(newPoint); beatmap.ControlPointInfo.EffectPoints.Add(newPoint);
} }
@ -385,6 +395,9 @@ namespace osu.Game.Beatmaps.Formats
if (newPoint.EquivalentTo(existing)) if (newPoint.EquivalentTo(existing))
return; return;
if (existing.Time == newPoint.Time)
beatmap.ControlPointInfo.SamplePoints.Remove(existing);
beatmap.ControlPointInfo.SamplePoints.Add(newPoint); beatmap.ControlPointInfo.SamplePoints.Add(newPoint);
} }

View File

@ -99,7 +99,9 @@ namespace osu.Game
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>(); private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
// todo: move this to SongSelect once Screen has the ability to unsuspend. // 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>()); [Cached]
[Cached(Type = typeof(IBindable<IEnumerable<Mod>>))]
private readonly Bindable<IEnumerable<Mod>> selectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
public OsuGame(string[] args = null) public OsuGame(string[] args = null)
{ {

View File

@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.States;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
namespace osu.Game.Overlays.Direct namespace osu.Game.Overlays.Direct
@ -26,12 +25,14 @@ namespace osu.Game.Overlays.Direct
private PlayButton playButton; private PlayButton playButton;
private Box progressBar; private Box progressBar;
private Container downloadContainer;
protected override bool FadePlayButton => false;
protected override PlayButton PlayButton => playButton; protected override PlayButton PlayButton => playButton;
protected override Box PreviewBar => progressBar; protected override Box PreviewBar => progressBar;
public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap) public DirectListPanel(BeatmapSetInfo beatmap)
: base(beatmap)
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = height; Height = height;
@ -66,30 +67,45 @@ namespace osu.Game.Overlays.Direct
Spacing = new Vector2(10, 0), Spacing = new Vector2(10, 0),
Children = new Drawable[] Children = new Drawable[]
{ {
playButton = new PlayButton(SetInfo)
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
Size = new Vector2(height / 2),
FillMode = FillMode.Fit,
Alpha = 0,
},
new FillFlowContainer new FillFlowContainer
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
new OsuSpriteText new FillFlowContainer
{ {
Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), AutoSizeAxes = Axes.Both,
TextSize = 18, Direction = FillDirection.Horizontal,
Font = @"Exo2.0-BoldItalic", Children = new Drawable[]
}, {
new OsuSpriteText playButton = new PlayButton(SetInfo)
{ {
Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), Origin = Anchor.CentreLeft,
Font = @"Exo2.0-BoldItalic", Anchor = Anchor.CentreLeft,
Size = new Vector2(height / 2),
FillMode = FillMode.Fit,
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new OsuSpriteText
{
Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
TextSize = 18,
Font = @"Exo2.0-BoldItalic",
},
new OsuSpriteText
{
Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
Font = @"Exo2.0-BoldItalic",
},
}
},
}
}, },
new FillFlowContainer new FillFlowContainer
{ {
@ -108,16 +124,13 @@ namespace osu.Game.Overlays.Direct
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
LayoutEasing = Easing.OutQuint,
LayoutDuration = transition_duration,
Children = new Drawable[] Children = new Drawable[]
{ {
downloadContainer = new Container new Container
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.CentreRight,
Origin = Anchor.TopRight, Origin = Anchor.CentreRight,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Alpha = 0,
Child = new DownloadButton(SetInfo) Child = new DownloadButton(SetInfo)
{ {
Size = new Vector2(height - vertical_padding * 3), Size = new Vector2(height - vertical_padding * 3),
@ -184,17 +197,5 @@ namespace osu.Game.Overlays.Direct
}, },
}); });
} }
protected override bool OnHover(InputState state)
{
downloadContainer.FadeIn(transition_duration, Easing.InOutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
downloadContainer.FadeOut(transition_duration, Easing.InOutQuint);
base.OnHoverLost(state);
}
} }
} }

View File

@ -40,6 +40,8 @@ namespace osu.Game.Overlays.Direct
protected abstract PlayButton PlayButton { get; } protected abstract PlayButton PlayButton { get; }
protected abstract Box PreviewBar { get; } protected abstract Box PreviewBar { get; }
protected virtual bool FadePlayButton => true;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
protected DirectPanel(BeatmapSetInfo setInfo) protected DirectPanel(BeatmapSetInfo setInfo)
@ -125,7 +127,8 @@ namespace osu.Game.Overlays.Direct
{ {
content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint);
content.MoveToY(-4, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint);
PlayButton.FadeIn(120, Easing.InOutQuint); if (FadePlayButton)
PlayButton.FadeIn(120, Easing.InOutQuint);
return base.OnHover(state); return base.OnHover(state);
} }
@ -134,7 +137,7 @@ namespace osu.Game.Overlays.Direct
{ {
content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint);
content.MoveToY(0, hover_transition_time, Easing.OutQuint); content.MoveToY(0, hover_transition_time, Easing.OutQuint);
if (!PreviewPlaying) if (FadePlayButton && !PreviewPlaying)
PlayButton.FadeOut(120, Easing.InOutQuint); PlayButton.FadeOut(120, Easing.InOutQuint);
base.OnHoverLost(state); base.OnHoverLost(state);

View File

@ -39,9 +39,39 @@ namespace osu.Game.Overlays.Mods
protected readonly FillFlowContainer<ModSection> ModSectionsContainer; protected readonly FillFlowContainer<ModSection> ModSectionsContainer;
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(); protected readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>(); protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IEnumerable<Mod>> selectedMods)
{
LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
Ruleset.BindTo(ruleset);
if (selectedMods != null) SelectedMods.BindTo(selectedMods);
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
}
protected override void LoadComplete()
{
base.LoadComplete();
Ruleset.BindValueChanged(rulesetChanged, true);
SelectedMods.BindValueChanged(selectedModsChanged, true);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
private void rulesetChanged(RulesetInfo newRuleset) private void rulesetChanged(RulesetInfo newRuleset)
{ {
@ -51,33 +81,16 @@ namespace osu.Game.Overlays.Mods
foreach (ModSection section in ModSectionsContainer.Children) foreach (ModSection section in ModSectionsContainer.Children)
section.Mods = instance.GetModsFor(section.ModType); section.Mods = instance.GetModsFor(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(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(); refreshSelectedMods();
} }
[BackgroundDependencyLoader]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio)
{
SelectedMods.ValueChanged += selectedModsChanged;
LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
Ruleset.BindTo(ruleset);
Ruleset.BindValueChanged(rulesetChanged, true);
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
private void selectedModsChanged(IEnumerable<Mod> obj) private void selectedModsChanged(IEnumerable<Mod> obj)
{ {
foreach (ModSection section in ModSectionsContainer.Children) foreach (ModSection section in ModSectionsContainer.Children)
@ -176,10 +189,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();
}
public ModSelectOverlay() public ModSelectOverlay()
{ {

View File

@ -50,13 +50,14 @@ namespace osu.Game.Screens.Select
private SampleChannel sampleConfirm; private SampleChannel sampleConfirm;
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>()); [Cached]
[Cached(Type = typeof(IBindable<IEnumerable<Mod>>))]
private readonly Bindable<IEnumerable<Mod>> selectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu) private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, Bindable<IEnumerable<Mod>> selectedMods)
{ {
if (osu != null) SelectedMods.BindTo(osu.SelectedMods); if (selectedMods != null) this.selectedMods.BindTo(selectedMods);
modSelect.SelectedMods.BindTo(SelectedMods);
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
@ -84,7 +85,7 @@ namespace osu.Game.Screens.Select
protected override void UpdateBeatmap(WorkingBeatmap beatmap) protected override void UpdateBeatmap(WorkingBeatmap beatmap)
{ {
beatmap.Mods.BindTo(SelectedMods); beatmap.Mods.BindTo(selectedMods);
base.UpdateBeatmap(beatmap); base.UpdateBeatmap(beatmap);
@ -131,7 +132,7 @@ 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;
SelectedMods.UnbindAll(); selectedMods.UnbindAll();
Beatmap.Value.Mods.Value = new Mod[] { }; Beatmap.Value.Mods.Value = new Mod[] { };
return false; return false;
@ -147,10 +148,10 @@ namespace osu.Game.Screens.Select
var auto = Ruleset.Value.CreateInstance().GetAutoplayMod(); var auto = Ruleset.Value.CreateInstance().GetAutoplayMod();
var autoType = auto.GetType(); var autoType = auto.GetType();
var mods = modSelect.SelectedMods.Value; var mods = selectedMods.Value;
if (mods.All(m => m.GetType() != autoType)) if (mods.All(m => m.GetType() != autoType))
{ {
modSelect.SelectedMods.Value = mods.Append(auto); selectedMods.Value = mods.Append(auto);
removeAutoModOnResume = true; removeAutoModOnResume = true;
} }
} }