diff --git a/osu.Android.props b/osu.Android.props
index 82dec74855..ff6499631d 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
index 346a09cac8..ab61b14ac4 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
@@ -5,10 +5,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Catch.MathUtils;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Utils;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
public void ApplyPositionOffsets(IBeatmap beatmap)
{
- var rng = new FastRandom(RNG_SEED);
+ var rng = new LegacyRandom(RNG_SEED);
float? lastPosition = null;
double lastStartTime = 0;
@@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
initialiseHyperDash(beatmap);
}
- private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng)
+ private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, LegacyRandom rng)
{
float offsetPosition = hitObject.OriginalX;
double startTime = hitObject.StartTime;
@@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
/// The position which the offset should be applied to.
/// The maximum offset, cannot exceed 20px.
/// The random number generator.
- private static void applyRandomOffset(ref float position, double maxOffset, FastRandom rng)
+ private static void applyRandomOffset(ref float position, double maxOffset, LegacyRandom rng)
{
bool right = rng.NextBool();
float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset)));
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
index 47e0e6d7b1..207c6907c8 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
@@ -11,8 +11,8 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Mania.Beatmaps.Patterns;
-using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy;
+using osu.Game.Utils;
using osuTK;
namespace osu.Game.Rulesets.Mania.Beatmaps
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
private readonly int originalTargetColumns;
// Internal for testing purposes
- internal FastRandom Random { get; private set; }
+ internal LegacyRandom Random { get; private set; }
private Pattern lastPattern = new Pattern();
@@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
IBeatmapDifficultyInfo difficulty = original.Difficulty;
int seed = (int)MathF.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)MathF.Round(difficulty.ApproachRate);
- Random = new FastRandom(seed);
+ Random = new LegacyRandom(seed);
return base.ConvertBeatmap(original, cancellationToken);
}
@@ -227,7 +227,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
///
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
{
- public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
+ public SpecificBeatmapPatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
index 5f8b58d94d..dafe65f415 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
@@ -8,12 +8,12 @@ using System.Linq;
using osu.Framework.Extensions.EnumExtensions;
using osu.Game.Audio;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats;
+using osu.Game.Utils;
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
@@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private PatternType convertType;
- public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
+ public DistanceObjectPatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
convertType = PatternType.None;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
index f816a70ab3..2265d3d347 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
@@ -2,13 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
-using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using System.Linq;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Utils;
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
@@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private readonly int endTime;
private readonly PatternType convertType;
- public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
+ public EndTimeObjectPatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
endTime = (int)((HitObject as IHasDuration)?.EndTime ?? 0);
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
index 53b059b4e2..41d4c9322b 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
@@ -9,11 +9,11 @@ using osuTK;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
-using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Game.Utils;
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private readonly PatternType convertType;
- public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density,
+ public HitObjectPatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density,
PatternType lastStair, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
index eaf0ea0f2b..d5689c047a 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
@@ -5,8 +5,8 @@ using System;
using System.Linq;
using JetBrains.Annotations;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Objects;
+using osu.Game.Utils;
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
@@ -23,14 +23,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
///
/// The random number generator to use.
///
- protected readonly FastRandom Random;
+ protected readonly LegacyRandom Random;
///
/// The beatmap which is being converted from.
///
protected readonly IBeatmap OriginalBeatmap;
- protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
+ protected PatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(hitObject, beatmap, previousPattern)
{
if (random == null) throw new ArgumentNullException(nameof(random));
diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
deleted file mode 100644
index a9cd7f2476..0000000000
--- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using System;
-
-namespace osu.Game.Rulesets.Mania.MathUtils
-{
- ///
- /// A PRNG specified in http://heliosphan.org/fastrandom.html.
- ///
- internal class FastRandom
- {
- private const double int_to_real = 1.0 / (int.MaxValue + 1.0);
- private const uint int_mask = 0x7FFFFFFF;
- private const uint y = 842502087;
- private const uint z = 3579807591;
- private const uint w = 273326509;
-
- internal uint X { get; private set; }
- internal uint Y { get; private set; } = y;
- internal uint Z { get; private set; } = z;
- internal uint W { get; private set; } = w;
-
- public FastRandom(int seed)
- {
- X = (uint)seed;
- }
-
- public FastRandom()
- : this(Environment.TickCount)
- {
- }
-
- ///
- /// Generates a random unsigned integer within the range [, ).
- ///
- /// The random value.
- public uint NextUInt()
- {
- uint t = X ^ (X << 11);
- X = Y;
- Y = Z;
- Z = W;
- return W = W ^ (W >> 19) ^ t ^ (t >> 8);
- }
-
- ///
- /// Generates a random integer value within the range [0, ).
- ///
- /// The random value.
- public int Next() => (int)(int_mask & NextUInt());
-
- ///
- /// Generates a random integer value within the range [0, ).
- ///
- /// The upper bound.
- /// The random value.
- public int Next(int upperBound) => (int)(NextDouble() * upperBound);
-
- ///
- /// Generates a random integer value within the range [, ).
- ///
- /// The lower bound of the range.
- /// The upper bound of the range.
- /// The random value.
- public int Next(int lowerBound, int upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound));
-
- ///
- /// Generates a random double value within the range [0, 1).
- ///
- /// The random value.
- public double NextDouble() => int_to_real * Next();
-
- private uint bitBuffer;
- private int bitIndex = 32;
-
- ///
- /// Generates a reandom boolean value. Cached such that a random value is only generated once in every 32 calls.
- ///
- /// The random value.
- public bool NextBool()
- {
- if (bitIndex == 32)
- {
- bitBuffer = NextUInt();
- bitIndex = 1;
-
- return (bitBuffer & 1) == 1;
- }
-
- bitIndex++;
- return ((bitBuffer >>= 1) & 1) == 1;
- }
- }
-}
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
index 0403e81229..429fe30fc5 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
@@ -9,6 +9,10 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModSuddenDeath : ModSuddenDeath
{
- public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
+ public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[]
+ {
+ typeof(OsuModAutopilot),
+ typeof(OsuModTarget),
+ }).ToArray();
}
}
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs
index 5285380097..4fab9b6a5a 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override string Description => @"Practice keeping up with the beat of the song.";
public override double ScoreMultiplier => 1;
- public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles) };
+ public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSuddenDeath) };
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
public Bindable Seed { get; } = new Bindable
diff --git a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
index 296c5cef76..a354464a8e 100644
--- a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
@@ -160,6 +160,40 @@ namespace osu.Game.Tests.Gameplay
assertHealthNotEqualTo(1);
}
+ [Test]
+ public void TestFailConditions()
+ {
+ var beatmap = createBeatmap(0, 1000);
+ createProcessor(beatmap);
+
+ AddStep("setup fail conditions", () => processor.FailConditions += ((_, result) => result.Type == HitResult.Miss));
+
+ AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
+ AddAssert("not failed", () => !processor.HasFailed);
+ AddStep("apply miss hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Miss }));
+ AddAssert("failed", () => processor.HasFailed);
+ }
+
+ [TestCase(HitResult.Miss)]
+ [TestCase(HitResult.Meh)]
+ public void TestMultipleFailConditions(HitResult resultApplied)
+ {
+ var beatmap = createBeatmap(0, 1000);
+ createProcessor(beatmap);
+
+ AddStep("setup multiple fail conditions", () =>
+ {
+ processor.FailConditions += ((_, result) => result.Type == HitResult.Miss);
+ processor.FailConditions += ((_, result) => result.Type == HitResult.Meh);
+ });
+
+ AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
+ AddAssert("not failed", () => !processor.HasFailed);
+
+ AddStep($"apply {resultApplied.ToString().ToLower()} hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = resultApplied }));
+ AddAssert("failed", () => processor.HasFailed);
+ }
+
[Test]
public void TestBonusObjectsExcludedFromDrain()
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs
index 5ca09b34aa..64ad4ff119 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs
@@ -1,13 +1,18 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Allocation;
using osu.Framework.Screens;
+using osu.Game.Overlays;
using osu.Game.Overlays.FirstRunSetup;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene
{
+ [Cached]
+ private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
+
public TestSceneFirstRunScreenUIScale()
{
AddStep("load screen", () =>
diff --git a/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs b/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs
index 54dcdc55e3..ad0ff876e8 100644
--- a/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs
+++ b/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs
@@ -28,11 +28,6 @@ namespace osu.Game.Beatmaps.Drawables
},
downloadTracker = new BeatmapDownloadTracker(beatmapSet),
};
- AddInternal(progressBar = new ProgressBar(false)
- {
- Height = 0,
- Alpha = 0,
- });
AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X;
diff --git a/osu.Game/Extensions/TimeDisplayExtensions.cs b/osu.Game/Extensions/TimeDisplayExtensions.cs
index 54af6a5942..98633958ee 100644
--- a/osu.Game/Extensions/TimeDisplayExtensions.cs
+++ b/osu.Game/Extensions/TimeDisplayExtensions.cs
@@ -3,6 +3,7 @@
using System;
using Humanizer;
+using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Localisation;
using osu.Game.Resources.Localisation.Web;
@@ -42,12 +43,12 @@ namespace osu.Game.Extensions
public static LocalisableString ToFormattedDuration(this TimeSpan timeSpan)
{
if (timeSpan.TotalDays >= 1)
- return new LocalisableFormattableString(timeSpan, @"dd\:hh\:mm\:ss");
+ return timeSpan.ToLocalisableString(@"dd\:hh\:mm\:ss");
if (timeSpan.TotalHours >= 1)
- return new LocalisableFormattableString(timeSpan, @"hh\:mm\:ss");
+ return timeSpan.ToLocalisableString(@"hh\:mm\:ss");
- return new LocalisableFormattableString(timeSpan, @"mm\:ss");
+ return timeSpan.ToLocalisableString(@"mm\:ss");
}
///
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index 20fa7d5148..b1d4691938 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -12,7 +12,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
-using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
@@ -131,22 +130,7 @@ namespace osu.Game.Graphics.UserInterface
BackgroundColourSelected = SelectionColour
};
- protected override ScrollContainer CreateScrollContainer(Direction direction) => new DropdownScrollContainer(direction);
-
- // Hotfix for https://github.com/ppy/osu/issues/17961
- public class DropdownScrollContainer : OsuScrollContainer
- {
- public DropdownScrollContainer(Direction direction)
- : base(direction)
- {
- }
-
- protected override bool OnMouseDown(MouseDownEvent e)
- {
- base.OnMouseDown(e);
- return true;
- }
- }
+ protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction);
#region DrawableOsuDropdownMenuItem
diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs
index bfdfd32fb3..a16adcbd57 100644
--- a/osu.Game/Graphics/UserInterface/OsuMenu.cs
+++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs
@@ -9,7 +9,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
-using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osuTK;
@@ -82,22 +81,7 @@ namespace osu.Game.Graphics.UserInterface
return new DrawableOsuMenuItem(item);
}
- protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuMenuScrollContainer(direction);
-
- // Hotfix for https://github.com/ppy/osu/issues/17961
- public class OsuMenuScrollContainer : OsuScrollContainer
- {
- public OsuMenuScrollContainer(Direction direction)
- : base(direction)
- {
- }
-
- protected override bool OnMouseDown(MouseDownEvent e)
- {
- base.OnMouseDown(e);
- return true;
- }
- }
+ protected override ScrollContainer CreateScrollContainer(Direction direction) => new OsuScrollContainer(direction);
protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical)
{
diff --git a/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs b/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs
index c6477d1781..f483e67b27 100644
--- a/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs
@@ -4,6 +4,8 @@
#nullable enable
using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@@ -31,6 +33,9 @@ namespace osu.Game.Graphics.UserInterfaceV2
private Color4 enabledColour;
private Color4 disabledColour;
+ private Sample? sampleChecked;
+ private Sample? sampleUnchecked;
+
public SwitchButton()
{
Size = new Vector2(45, 20);
@@ -70,13 +75,16 @@ namespace osu.Game.Graphics.UserInterfaceV2
}
[BackgroundDependencyLoader(true)]
- private void load(OverlayColourProvider? colourProvider, OsuColour colours)
+ private void load(OverlayColourProvider? colourProvider, OsuColour colours, AudioManager audio)
{
enabledColour = colourProvider?.Highlight1 ?? colours.BlueDark;
disabledColour = colourProvider?.Background3 ?? colours.Gray3;
switchContainer.Colour = enabledColour;
fill.Colour = disabledColour;
+
+ sampleChecked = audio.Samples.Get(@"UI/check-on");
+ sampleUnchecked = audio.Samples.Get(@"UI/check-off");
}
protected override void LoadComplete()
@@ -107,6 +115,16 @@ namespace osu.Game.Graphics.UserInterfaceV2
base.OnHoverLost(e);
}
+ protected override void OnUserChange(bool value)
+ {
+ base.OnUserChange(value);
+
+ if (value)
+ sampleChecked?.Play();
+ else
+ sampleUnchecked?.Play();
+ }
+
private void updateBorder()
{
circularContainer.TransformBorderTo((Current.Value ? enabledColour : disabledColour).Lighten(IsHovered ? 0.3f : 0));
diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs
index e4fda9d9c3..1f9a63e3b9 100644
--- a/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs
+++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs
@@ -72,7 +72,8 @@ namespace osu.Game.Overlays.BeatmapListing
Size = new Vector2(12),
Icon = getIconForCardSize(Value)
}
- }
+ },
+ new HoverClickSounds(HoverSampleSet.TabSelect)
};
}
diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs
index ec795cf6b2..9ee002fd9d 100644
--- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs
+++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs
@@ -119,7 +119,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
maxComboColumn.Text = value.MaxCombo.ToLocalisableString(@"0\x");
ppColumn.Alpha = value.BeatmapInfo.Status.GrantsPerformancePoints() ? 1 : 0;
- ppColumn.Text = value.PP?.ToLocalisableString(@"N0");
+ ppColumn.Text = value.PP?.ToLocalisableString(@"N0") ?? default(LocalisableString);
statisticsColumns.ChildrenEnumerable = value.GetStatisticsForDisplay().Select(createStatisticsColumn);
modsColumn.Mods = value.Mods;
diff --git a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs
index 8fcfdbf689..0016793cad 100644
--- a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs
+++ b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs
@@ -1,10 +1,14 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Allocation;
+using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
+using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Sprites;
using osuTK;
namespace osu.Game.Overlays.FirstRunSetup
@@ -15,20 +19,34 @@ namespace osu.Game.Overlays.FirstRunSetup
protected FillFlowContainer Content { get; private set; }
- protected FirstRunSetupScreen()
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider overlayColourProvider)
{
+ const float header_size = 40;
+ const float spacing = 20;
+
InternalChildren = new Drawable[]
{
new OsuScrollContainer(Direction.Vertical)
{
RelativeSizeAxes = Axes.Both,
ScrollbarOverlapsContent = false,
- Child = Content = new FillFlowContainer
+ Children = new Drawable[]
{
- Spacing = new Vector2(20),
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
+ new OsuSpriteText
+ {
+ Text = this.GetLocalisableDescription(),
+ Font = OsuFont.Default.With(size: header_size),
+ Colour = overlayColourProvider.Light1,
+ },
+ Content = new FillFlowContainer
+ {
+ Y = header_size + spacing,
+ Spacing = new Vector2(spacing),
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ }
},
}
};
diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs
index db7659e87a..dc3d40ad95 100644
--- a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs
+++ b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs
@@ -5,6 +5,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Localisation;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@@ -15,6 +16,7 @@ using osu.Game.Overlays.Settings.Sections;
namespace osu.Game.Overlays.FirstRunSetup
{
+ [LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.Behaviour))]
public class ScreenBehaviour : FirstRunSetupScreen
{
private SearchContainer searchContainer;
diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs
index ef48d9ced5..1bd82f6d99 100644
--- a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs
+++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs
@@ -27,6 +27,7 @@ using osuTK;
namespace osu.Game.Overlays.FirstRunSetup
{
+ [LocalisableDescription(typeof(GraphicsSettingsStrings), nameof(GraphicsSettingsStrings.UIScaling))]
public class ScreenUIScale : FirstRunSetupScreen
{
[BackgroundDependencyLoader]
diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs
index 39da180f40..10e15a7555 100644
--- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs
+++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs
@@ -1,16 +1,20 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Localisation;
namespace osu.Game.Overlays.FirstRunSetup
{
+ [LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.WelcomeTitle))]
public class ScreenWelcome : FirstRunSetupScreen
{
- public ScreenWelcome()
+ [BackgroundDependencyLoader]
+ private void load()
{
Content.Children = new Drawable[]
{
diff --git a/osu.Game/Overlays/FirstRunSetupOverlay.cs b/osu.Game/Overlays/FirstRunSetupOverlay.cs
index 9a9e88f900..6fcc86e1f1 100644
--- a/osu.Game/Overlays/FirstRunSetupOverlay.cs
+++ b/osu.Game/Overlays/FirstRunSetupOverlay.cs
@@ -7,6 +7,7 @@ using System;
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -56,11 +57,11 @@ namespace osu.Game.Overlays
///
public FirstRunSetupScreen? CurrentScreen => (FirstRunSetupScreen?)stack?.CurrentScreen;
- private readonly FirstRunStep[] steps =
+ private readonly Type[] steps =
{
- new FirstRunStep(typeof(ScreenWelcome), FirstRunSetupOverlayStrings.WelcomeTitle),
- new FirstRunStep(typeof(ScreenUIScale), GraphicsSettingsStrings.UIScaling),
- new FirstRunStep(typeof(ScreenBehaviour), FirstRunSetupOverlayStrings.Behaviour),
+ typeof(ScreenWelcome),
+ typeof(ScreenUIScale),
+ typeof(ScreenBehaviour),
};
private Container stackContainer = null!;
@@ -287,7 +288,7 @@ namespace osu.Game.Overlays
if (currentStepIndex < steps.Length)
{
- stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value].ScreenType));
+ stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value]));
}
else
{
@@ -318,23 +319,11 @@ namespace osu.Game.Overlays
}
else
{
- BackButton.Text = new TranslatableString(@"_", @"{0} ({1})", CommonStrings.Back, steps[currentStepIndex.Value - 1].Description);
+ BackButton.Text = LocalisableString.Interpolate($@"{CommonStrings.Back} ({steps[currentStepIndex.Value - 1].GetLocalisableDescription()})");
NextButton.Text = isLastStep
? CommonStrings.Finish
- : new TranslatableString(@"_", @"{0} ({1})", CommonStrings.Next, steps[currentStepIndex.Value + 1].Description);
- }
- }
-
- private class FirstRunStep
- {
- public readonly Type ScreenType;
- public readonly LocalisableString Description;
-
- public FirstRunStep(Type screenType, LocalisableString description)
- {
- ScreenType = screenType;
- Description = description;
+ : LocalisableString.Interpolate($@"{CommonStrings.Next} ({steps[currentStepIndex.Value + 1].GetLocalisableDescription()})");
}
}
}
diff --git a/osu.Game/Overlays/Mods/ModColumn.cs b/osu.Game/Overlays/Mods/ModColumn.cs
index 1157c0c0c6..6a2c2adcba 100644
--- a/osu.Game/Overlays/Mods/ModColumn.cs
+++ b/osu.Game/Overlays/Mods/ModColumn.cs
@@ -441,7 +441,7 @@ namespace osu.Game.Overlays.Mods
protected override bool OnKeyDown(KeyDownEvent e)
{
- if (e.ControlPressed || e.AltPressed) return false;
+ if (e.ControlPressed || e.AltPressed || e.SuperPressed) return false;
if (toggleKeys == null) return false;
int index = Array.IndexOf(toggleKeys, e.Key);
diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs
index d4dde0db3f..5f5cfce344 100644
--- a/osu.Game/Overlays/OverlaySortTabControl.cs
+++ b/osu.Game/Overlays/OverlaySortTabControl.cs
@@ -149,7 +149,7 @@ namespace osu.Game.Overlays
}
});
- AddInternal(new HoverClickSounds());
+ AddInternal(new HoverClickSounds(HoverSampleSet.TabSelect));
}
protected override void LoadComplete()
diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs
index 8f6b935128..ec9cb55042 100644
--- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs
@@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
private void updateProgress(APIUser user)
{
levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0;
- levelProgressText.Text = user?.Statistics?.Level.Progress.ToLocalisableString("0'%'");
+ levelProgressText.Text = user?.Statistics?.Level.Progress.ToLocalisableString("0'%'") ?? default(LocalisableString);
}
}
}
diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs
index dfa45cc543..48a4c31f30 100644
--- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs
+++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs
@@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Rankings
startDateColumn.Value = dateToString(response.Spotlight.StartDate);
endDateColumn.Value = dateToString(response.Spotlight.EndDate);
mapCountColumn.Value = response.BeatmapSets.Count.ToLocalisableString(@"N0");
- participantsColumn.Value = response.Spotlight.Participants?.ToLocalisableString(@"N0");
+ participantsColumn.Value = response.Spotlight.Participants?.ToLocalisableString(@"N0") ?? default(LocalisableString);
}
private LocalisableString dateToString(DateTimeOffset date) => date.ToLocalisableString(@"yyyy-MM-dd");
diff --git a/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs b/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs
index 17c17b1f1a..bdbd2942d1 100644
--- a/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs
+++ b/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Localisation;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Users;
@@ -24,7 +25,7 @@ namespace osu.Game.Overlays.Rankings.Tables
protected override Drawable[] CreateUniqueContent(UserStatistics item) => new Drawable[]
{
- new RowText { Text = item.PP?.ToLocalisableString(@"N0"), }
+ new RowText { Text = item.PP?.ToLocalisableString(@"N0") ?? default(LocalisableString), }
};
}
}
diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
index a92c30e593..0f51560476 100644
--- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
@@ -43,11 +43,11 @@ namespace osu.Game.Rulesets.Scoring
Health.Value += GetHealthIncreaseFor(result);
- if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
- return;
-
- if (Failed?.Invoke() != false)
- HasFailed = true;
+ if (meetsAnyFailCondition(result))
+ {
+ if (Failed?.Invoke() != false)
+ HasFailed = true;
+ }
}
protected override void RevertResultInternal(JudgementResult result)
@@ -69,6 +69,28 @@ namespace osu.Game.Rulesets.Scoring
///
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
+ ///
+ /// Whether the current state of or the provided meets any fail condition.
+ ///
+ /// The judgement result.
+ private bool meetsAnyFailCondition(JudgementResult result)
+ {
+ if (DefaultFailCondition)
+ return true;
+
+ if (FailConditions != null)
+ {
+ foreach (var condition in FailConditions.GetInvocationList())
+ {
+ bool conditionResult = (bool)condition.Method.Invoke(condition.Target, new object[] { this, result });
+ if (conditionResult)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
protected override void Reset(bool storeResults)
{
base.Reset(storeResults);
diff --git a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs
index 42091c521f..1662ca399f 100644
--- a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs
@@ -99,8 +99,8 @@ namespace osu.Game.Screens.Play.PlayerSettings
{
public override LocalisableString TooltipText =>
Current.Value == 0
- ? new TranslatableString("_", @"{0} ms", base.TooltipText)
- : new TranslatableString("_", @"{0} ms {1}", base.TooltipText, getEarlyLateText(Current.Value));
+ ? LocalisableString.Interpolate($@"{base.TooltipText} ms")
+ : LocalisableString.Interpolate($@"{base.TooltipText} ms {getEarlyLateText(Current.Value)}");
private LocalisableString getEarlyLateText(double value)
{
diff --git a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs b/osu.Game/Utils/LegacyRandom.cs
similarity index 79%
rename from osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs
rename to osu.Game/Utils/LegacyRandom.cs
index 46e427e1b7..cf731aa91f 100644
--- a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs
+++ b/osu.Game/Utils/LegacyRandom.cs
@@ -2,27 +2,36 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using osu.Framework.Utils;
-namespace osu.Game.Rulesets.Catch.MathUtils
+namespace osu.Game.Utils
{
///
/// A PRNG specified in http://heliosphan.org/fastrandom.html.
+ /// Should only be used to match legacy behaviour. See for a newer alternative.
///
- public class FastRandom
+ ///
+ /// Known in osu-stable code as `FastRandom`.
+ ///
+ public class LegacyRandom
{
private const double int_to_real = 1.0 / (int.MaxValue + 1.0);
private const uint int_mask = 0x7FFFFFFF;
- private const uint y_initial = 842502087;
- private const uint z_initial = 3579807591;
- private const uint w_initial = 273326509;
- private uint x, y = y_initial, z = z_initial, w = w_initial;
+ private const uint y = 842502087;
+ private const uint z = 3579807591;
+ private const uint w = 273326509;
- public FastRandom(int seed)
+ public uint X { get; private set; }
+ public uint Y { get; private set; } = y;
+ public uint Z { get; private set; } = z;
+ public uint W { get; private set; } = w;
+
+ public LegacyRandom(int seed)
{
- x = (uint)seed;
+ X = (uint)seed;
}
- public FastRandom()
+ public LegacyRandom()
: this(Environment.TickCount)
{
}
@@ -33,11 +42,11 @@ namespace osu.Game.Rulesets.Catch.MathUtils
/// The random value.
public uint NextUInt()
{
- uint t = x ^ (x << 11);
- x = y;
- y = z;
- z = w;
- return w = w ^ (w >> 19) ^ t ^ (t >> 8);
+ uint t = X ^ (X << 11);
+ X = Y;
+ Y = Z;
+ Z = W;
+ return W = W ^ (W >> 19) ^ t ^ (t >> 8);
}
///
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 325e834fa5..26891ad978 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -35,7 +35,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 8775442be2..d261e13ade 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,7 +61,7 @@
-
+
@@ -84,7 +84,7 @@
-
+