Merge branch 'master' into new-difficulty-creation-v3

This commit is contained in:
Bartłomiej Dach 2022-02-03 16:36:18 +01:00
commit b7d7e6612e
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
6 changed files with 96 additions and 25 deletions

View File

@ -128,6 +128,7 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("choose clear all scores", () => InputManager.Key(Key.Number4)); AddStep("choose clear all scores", () => InputManager.Key(Key.Number4));
AddUntilStep("wait for dialog display", () => Game.Dependencies.Get<DialogOverlay>().IsLoaded);
AddUntilStep("wait for dialog", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog != null); AddUntilStep("wait for dialog", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog != null);
AddStep("confirm deletion", () => InputManager.Key(Key.Number1)); AddStep("confirm deletion", () => InputManager.Key(Key.Number1));
AddUntilStep("wait for dialog dismissed", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog == null); AddUntilStep("wait for dialog dismissed", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog == null);
@ -172,6 +173,7 @@ namespace osu.Game.Tests.Visual.Navigation
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddUntilStep("wait for dialog display", () => Game.Dependencies.Get<DialogOverlay>().IsLoaded);
AddUntilStep("wait for dialog", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog != null); AddUntilStep("wait for dialog", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog != null);
AddStep("confirm deletion", () => InputManager.Key(Key.Number1)); AddStep("confirm deletion", () => InputManager.Key(Key.Number1));
AddUntilStep("wait for dialog dismissed", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog == null); AddUntilStep("wait for dialog dismissed", () => Game.Dependencies.Get<DialogOverlay>().CurrentDialog == null);

View File

@ -601,7 +601,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
BeatmapSetInfo testMixed = null; BeatmapSetInfo testMixed = null;
createCarousel(); createCarousel(new List<BeatmapSetInfo>());
AddStep("add mixed ruleset beatmapset", () => AddStep("add mixed ruleset beatmapset", () =>
{ {
@ -765,22 +765,22 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
bool changed = false; bool changed = false;
createCarousel(c => if (beatmapSets == null)
{
beatmapSets = new List<BeatmapSetInfo>();
for (int i = 1; i <= (count ?? set_count); i++)
{
beatmapSets.Add(randomDifficulties
? TestResources.CreateTestBeatmapSetInfo()
: TestResources.CreateTestBeatmapSetInfo(3));
}
}
createCarousel(beatmapSets, c =>
{ {
carouselAdjust?.Invoke(c); carouselAdjust?.Invoke(c);
if (beatmapSets == null)
{
beatmapSets = new List<BeatmapSetInfo>();
for (int i = 1; i <= (count ?? set_count); i++)
{
beatmapSets.Add(randomDifficulties
? TestResources.CreateTestBeatmapSetInfo()
: TestResources.CreateTestBeatmapSetInfo(3));
}
}
carousel.Filter(initialCriteria?.Invoke() ?? new FilterCriteria()); carousel.Filter(initialCriteria?.Invoke() ?? new FilterCriteria());
carousel.BeatmapSetsChanged = () => changed = true; carousel.BeatmapSetsChanged = () => changed = true;
carousel.BeatmapSets = beatmapSets; carousel.BeatmapSets = beatmapSets;
@ -789,7 +789,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("Wait for load", () => changed); AddUntilStep("Wait for load", () => changed);
} }
private void createCarousel(Action<BeatmapCarousel> carouselAdjust = null, Container target = null) private void createCarousel(List<BeatmapSetInfo> beatmapSets, Action<BeatmapCarousel> carouselAdjust = null, Container target = null)
{ {
AddStep("Create carousel", () => AddStep("Create carousel", () =>
{ {
@ -803,6 +803,8 @@ namespace osu.Game.Tests.Visual.SongSelect
carouselAdjust?.Invoke(carousel); carouselAdjust?.Invoke(carousel);
carousel.BeatmapSets = beatmapSets;
(target ?? this).Child = carousel; (target ?? this).Child = carousel;
}); });
} }

View File

@ -399,7 +399,10 @@ namespace osu.Game.Online.API
lock (queue) lock (queue)
{ {
if (state.Value == APIState.Offline) if (state.Value == APIState.Offline)
{
request.Fail(new WebException(@"User not logged in"));
return; return;
}
queue.Enqueue(request); queue.Enqueue(request);
} }
@ -416,7 +419,7 @@ namespace osu.Game.Online.API
if (failOldRequests) if (failOldRequests)
{ {
foreach (var req in oldQueueRequests) foreach (var req in oldQueueRequests)
req.Fail(new WebException(@"Disconnected from server")); req.Fail(new WebException($@"Request failed from flush operation (state {state.Value})"));
} }
} }
} }

View File

@ -17,6 +17,7 @@ using osu.Game.Input.Bindings;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osu.Game.Skinning; using osu.Game.Skinning;
@ -83,10 +84,7 @@ namespace osu.Game.Screens.Play
Children = new Drawable[] Children = new Drawable[]
{ {
CreateFailingLayer(), CreateFailingLayer(),
mainComponents = new SkinnableTargetContainer(SkinnableTarget.MainHUDComponents) mainComponents = new MainComponentsContainer(),
{
RelativeSizeAxes = Axes.Both,
},
topRightElements = new FillFlowContainer topRightElements = new FillFlowContainer
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
@ -325,5 +323,29 @@ namespace osu.Game.Screens.Play
break; break;
} }
} }
private class MainComponentsContainer : SkinnableTargetContainer
{
private Bindable<ScoringMode> scoringMode;
[Resolved]
private OsuConfigManager config { get; set; }
public MainComponentsContainer()
: base(SkinnableTarget.MainHUDComponents)
{
RelativeSizeAxes = Axes.Both;
}
protected override void LoadComplete()
{
base.LoadComplete();
// When the scoring mode changes, relative positions of elements may change (see DefaultSkin.GetDrawableComponent).
// This is a best effort implementation for cases where users haven't customised layouts.
scoringMode = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode);
scoringMode.BindValueChanged(val => Reload());
}
}
} }
} }

View File

@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Caching; using osu.Framework.Caching;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -106,7 +108,7 @@ namespace osu.Game.Screens.Select
set set
{ {
loadedTestBeatmaps = true; loadedTestBeatmaps = true;
loadBeatmapSets(value); Schedule(() => loadBeatmapSets(value));
} }
} }
@ -151,6 +153,10 @@ namespace osu.Game.Screens.Select
private readonly DrawablePool<DrawableCarouselBeatmapSet> setPool = new DrawablePool<DrawableCarouselBeatmapSet>(100); private readonly DrawablePool<DrawableCarouselBeatmapSet> setPool = new DrawablePool<DrawableCarouselBeatmapSet>(100);
private Sample spinSample;
private int visibleSetsCount;
public BeatmapCarousel() public BeatmapCarousel()
{ {
root = new CarouselRoot(this); root = new CarouselRoot(this);
@ -169,8 +175,10 @@ namespace osu.Game.Screens.Select
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config, AudioManager audio)
{ {
spinSample = audio.Samples.Get("SongSelect/random-spin");
config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm);
config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled); config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled);
@ -419,6 +427,9 @@ namespace osu.Game.Screens.Select
return false; return false;
var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList();
visibleSetsCount = visibleSets.Count;
if (!visibleSets.Any()) if (!visibleSets.Any())
return false; return false;
@ -450,6 +461,9 @@ namespace osu.Game.Screens.Select
else else
set = visibleSets.ElementAt(RNG.Next(visibleSets.Count)); set = visibleSets.ElementAt(RNG.Next(visibleSets.Count));
if (selectedBeatmapSet != null)
playSpinSample(distanceBetween(set, selectedBeatmapSet));
select(set); select(set);
return true; return true;
} }
@ -464,12 +478,25 @@ namespace osu.Game.Screens.Select
{ {
if (RandomAlgorithm.Value == RandomSelectAlgorithm.RandomPermutation) if (RandomAlgorithm.Value == RandomSelectAlgorithm.RandomPermutation)
previouslyVisitedRandomSets.Remove(selectedBeatmapSet); previouslyVisitedRandomSets.Remove(selectedBeatmapSet);
if (selectedBeatmapSet != null)
playSpinSample(distanceBetween(beatmap, selectedBeatmapSet));
select(beatmap); select(beatmap);
break; break;
} }
} }
} }
private double distanceBetween(CarouselItem item1, CarouselItem item2) => Math.Ceiling(Math.Abs(item1.CarouselYPosition - item2.CarouselYPosition) / DrawableCarouselItem.MAX_HEIGHT);
private void playSpinSample(double distance)
{
var chan = spinSample.GetChannel();
chan.Frequency.Value = 1f + Math.Min(1f, distance / visibleSetsCount);
chan.Play();
}
private void select(CarouselItem item) private void select(CarouselItem item)
{ {
if (!AllowSelection) if (!AllowSelection)

View File

@ -100,6 +100,7 @@ namespace osu.Game.Screens.Select
private Sample sampleChangeDifficulty; private Sample sampleChangeDifficulty;
private Sample sampleChangeBeatmap; private Sample sampleChangeBeatmap;
private Sample sampleRandomBeatmap;
private Container carouselContainer; private Container carouselContainer;
@ -109,6 +110,8 @@ namespace osu.Game.Screens.Select
private double audioFeedbackLastPlaybackTime; private double audioFeedbackLastPlaybackTime;
private bool randomSelectionPending;
[Resolved] [Resolved]
private MusicController music { get; set; } private MusicController music { get; set; }
@ -288,6 +291,7 @@ namespace osu.Game.Screens.Select
sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty"); sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty");
sampleChangeBeatmap = audio.Samples.Get(@"SongSelect/select-expand"); sampleChangeBeatmap = audio.Samples.Get(@"SongSelect/select-expand");
sampleRandomBeatmap = audio.Samples.Get(@"SongSelect/select-random");
SampleConfirm = audio.Samples.Get(@"SongSelect/confirm-selection"); SampleConfirm = audio.Samples.Get(@"SongSelect/confirm-selection");
if (dialogOverlay != null) if (dialogOverlay != null)
@ -315,8 +319,16 @@ namespace osu.Game.Screens.Select
(new FooterButtonMods { Current = Mods }, ModSelect), (new FooterButtonMods { Current = Mods }, ModSelect),
(new FooterButtonRandom (new FooterButtonRandom
{ {
NextRandom = () => Carousel.SelectNextRandom(), NextRandom = () =>
PreviousRandom = Carousel.SelectPreviousRandom {
randomSelectionPending = true;
Carousel.SelectNextRandom();
},
PreviousRandom = () =>
{
randomSelectionPending = true;
Carousel.SelectPreviousRandom();
}
}, null), }, null),
(new FooterButtonOptions(), BeatmapOptions) (new FooterButtonOptions(), BeatmapOptions)
}; };
@ -486,7 +498,9 @@ namespace osu.Game.Screens.Select
{ {
if (beatmap != null && beatmapInfoPrevious != null && Time.Current - audioFeedbackLastPlaybackTime >= 50) if (beatmap != null && beatmapInfoPrevious != null && Time.Current - audioFeedbackLastPlaybackTime >= 50)
{ {
if (beatmap.BeatmapSet?.ID == beatmapInfoPrevious.BeatmapSet?.ID) if (randomSelectionPending)
sampleRandomBeatmap.Play();
else if (beatmap.BeatmapSet?.ID == beatmapInfoPrevious.BeatmapSet?.ID)
sampleChangeDifficulty.Play(); sampleChangeDifficulty.Play();
else else
sampleChangeBeatmap.Play(); sampleChangeBeatmap.Play();
@ -494,6 +508,7 @@ namespace osu.Game.Screens.Select
audioFeedbackLastPlaybackTime = Time.Current; audioFeedbackLastPlaybackTime = Time.Current;
} }
randomSelectionPending = false;
beatmapInfoPrevious = beatmap; beatmapInfoPrevious = beatmap;
} }