mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 23:53:51 +09:00
Merge branch 'master' into move-difficulty-graph-toggle
This commit is contained in:
@ -191,4 +191,5 @@ dotnet_diagnostic.CA2225.severity = none
|
|||||||
# Banned APIs
|
# Banned APIs
|
||||||
dotnet_diagnostic.RS0030.severity = error
|
dotnet_diagnostic.RS0030.severity = error
|
||||||
|
|
||||||
|
dotnet_diagnostic.OLOC001.words_in_name = 5
|
||||||
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.
|
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.423.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.428.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -5,10 +5,10 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||||
{
|
{
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
|
|
||||||
public void ApplyPositionOffsets(IBeatmap beatmap)
|
public void ApplyPositionOffsets(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var rng = new FastRandom(RNG_SEED);
|
var rng = new LegacyRandom(RNG_SEED);
|
||||||
|
|
||||||
float? lastPosition = null;
|
float? lastPosition = null;
|
||||||
double lastStartTime = 0;
|
double lastStartTime = 0;
|
||||||
@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
initialiseHyperDash(beatmap);
|
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;
|
float offsetPosition = hitObject.OriginalX;
|
||||||
double startTime = hitObject.StartTime;
|
double startTime = hitObject.StartTime;
|
||||||
@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
/// <param name="position">The position which the offset should be applied to.</param>
|
/// <param name="position">The position which the offset should be applied to.</param>
|
||||||
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
|
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
|
||||||
/// <param name="rng">The random number generator.</param>
|
/// <param name="rng">The random number generator.</param>
|
||||||
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();
|
bool right = rng.NextBool();
|
||||||
float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset)));
|
float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset)));
|
||||||
|
@ -11,8 +11,8 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps.Patterns;
|
using osu.Game.Rulesets.Mania.Beatmaps.Patterns;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy;
|
using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy;
|
||||||
|
using osu.Game.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps
|
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||||
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
private readonly int originalTargetColumns;
|
private readonly int originalTargetColumns;
|
||||||
|
|
||||||
// Internal for testing purposes
|
// Internal for testing purposes
|
||||||
internal FastRandom Random { get; private set; }
|
internal LegacyRandom Random { get; private set; }
|
||||||
|
|
||||||
private Pattern lastPattern = new Pattern();
|
private Pattern lastPattern = new Pattern();
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
IBeatmapDifficultyInfo difficulty = original.Difficulty;
|
IBeatmapDifficultyInfo difficulty = original.Difficulty;
|
||||||
|
|
||||||
int seed = (int)MathF.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)MathF.Round(difficulty.ApproachRate);
|
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);
|
return base.ConvertBeatmap(original, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
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)
|
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ using System.Linq;
|
|||||||
using osu.Framework.Extensions.EnumExtensions;
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private PatternType convertType;
|
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)
|
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
|
||||||
{
|
{
|
||||||
convertType = PatternType.None;
|
convertType = PatternType.None;
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
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 int endTime;
|
||||||
private readonly PatternType convertType;
|
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)
|
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
|
||||||
{
|
{
|
||||||
endTime = (int)((HitObject as IHasDuration)?.EndTime ?? 0);
|
endTime = (int)((HitObject as IHasDuration)?.EndTime ?? 0);
|
||||||
|
@ -9,11 +9,11 @@ using osuTK;
|
|||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private readonly PatternType convertType;
|
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)
|
PatternType lastStair, IBeatmap originalBeatmap)
|
||||||
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
|
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
|
||||||
{
|
{
|
||||||
|
@ -5,8 +5,8 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||||
{
|
{
|
||||||
@ -23,14 +23,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The random number generator to use.
|
/// The random number generator to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly FastRandom Random;
|
protected readonly LegacyRandom Random;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beatmap which <see cref="HitObject"/> is being converted from.
|
/// The beatmap which <see cref="HitObject"/> is being converted from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly IBeatmap OriginalBeatmap;
|
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)
|
: base(hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
if (random == null) throw new ArgumentNullException(nameof(random));
|
if (random == null) throw new ArgumentNullException(nameof(random));
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
// 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;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.MathUtils
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A PRNG specified in http://heliosphan.org/fastrandom.html.
|
|
||||||
/// </summary>
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a random unsigned integer within the range [<see cref="uint.MinValue"/>, <see cref="uint.MaxValue"/>).
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public uint NextUInt()
|
|
||||||
{
|
|
||||||
uint t = X ^ (X << 11);
|
|
||||||
X = Y;
|
|
||||||
Y = Z;
|
|
||||||
Z = W;
|
|
||||||
return W = W ^ (W >> 19) ^ t ^ (t >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a random integer value within the range [0, <see cref="int.MaxValue"/>).
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public int Next() => (int)(int_mask & NextUInt());
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a random integer value within the range [0, <paramref name="upperBound"/>).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="upperBound">The upper bound.</param>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public int Next(int upperBound) => (int)(NextDouble() * upperBound);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a random integer value within the range [<paramref name="lowerBound"/>, <paramref name="upperBound"/>).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="lowerBound">The lower bound of the range.</param>
|
|
||||||
/// <param name="upperBound">The upper bound of the range.</param>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public int Next(int lowerBound, int upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a random double value within the range [0, 1).
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public double NextDouble() => int_to_real * Next();
|
|
||||||
|
|
||||||
private uint bitBuffer;
|
|
||||||
private int bitIndex = 32;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a reandom boolean value. Cached such that a random value is only generated once in every 32 calls.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The random value.</returns>
|
|
||||||
public bool NextBool()
|
|
||||||
{
|
|
||||||
if (bitIndex == 32)
|
|
||||||
{
|
|
||||||
bitBuffer = NextUInt();
|
|
||||||
bitIndex = 1;
|
|
||||||
|
|
||||||
return (bitBuffer & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitIndex++;
|
|
||||||
return ((bitBuffer >>= 1) & 1) == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
ClassicDefault = false,
|
||||||
LabelText = "Snaking out sliders",
|
LabelText = "Snaking out sliders",
|
||||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
[Ignore("Only for visual testing")]
|
||||||
|
public class TestSceneBundledBeatmapDownloader : OsuTestScene
|
||||||
|
{
|
||||||
|
private BundledBeatmapDownloader downloader;
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDownloader()
|
||||||
|
{
|
||||||
|
AddStep("Create downloader", () =>
|
||||||
|
{
|
||||||
|
downloader?.Expire();
|
||||||
|
Add(downloader = new BundledBeatmapDownloader(false));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.FirstRunSetup;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
public class TestSceneFirstRunScreenBehaviour : OsuManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
[Cached]
|
||||||
|
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
|
public TestSceneFirstRunScreenBehaviour()
|
||||||
|
{
|
||||||
|
AddStep("load screen", () =>
|
||||||
|
{
|
||||||
|
Child = new ScreenStack(new ScreenBehaviour());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.FirstRunSetup;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
public class TestSceneFirstRunScreenBundledBeatmaps : OsuManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
[Cached]
|
||||||
|
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
|
public TestSceneFirstRunScreenBundledBeatmaps()
|
||||||
|
{
|
||||||
|
AddStep("load screen", () =>
|
||||||
|
{
|
||||||
|
Child = new ScreenStack(new ScreenBeatmaps());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,18 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.FirstRunSetup;
|
using osu.Game.Overlays.FirstRunSetup;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.UserInterface
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
{
|
{
|
||||||
public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene
|
public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
|
[Cached]
|
||||||
|
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
public TestSceneFirstRunScreenUIScale()
|
public TestSceneFirstRunScreenUIScale()
|
||||||
{
|
{
|
||||||
AddStep("load screen", () =>
|
AddStep("load screen", () =>
|
||||||
|
@ -178,7 +178,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
AddStep("step to next", () => overlay.NextButton.TriggerClick());
|
AddStep("step to next", () => overlay.NextButton.TriggerClick());
|
||||||
|
|
||||||
AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenUIScale);
|
AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenBeatmaps);
|
||||||
|
|
||||||
AddStep("hide", () => overlay.Hide());
|
AddStep("hide", () => overlay.Hide());
|
||||||
AddAssert("overlay hidden", () => overlay.State.Value == Visibility.Hidden);
|
AddAssert("overlay hidden", () => overlay.State.Value == Visibility.Hidden);
|
||||||
@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("run notification action", () => lastNotification.Activated());
|
AddStep("run notification action", () => lastNotification.Activated());
|
||||||
|
|
||||||
AddAssert("overlay shown", () => overlay.State.Value == Visibility.Visible);
|
AddAssert("overlay shown", () => overlay.State.Value == Visibility.Visible);
|
||||||
AddAssert("is resumed", () => overlay.CurrentScreen is ScreenUIScale);
|
AddAssert("is resumed", () => overlay.CurrentScreen is ScreenBeatmaps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,33 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModMirror)));
|
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModMirror)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDimmedState()
|
||||||
|
{
|
||||||
|
createScreen();
|
||||||
|
changeRuleset(0);
|
||||||
|
|
||||||
|
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
||||||
|
|
||||||
|
ModColumn lastColumn = null;
|
||||||
|
|
||||||
|
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
|
||||||
|
AddStep("request scroll to last column", () =>
|
||||||
|
{
|
||||||
|
var lastDimContainer = this.ChildrenOfType<ModSelectScreen.ColumnDimContainer>().Last();
|
||||||
|
lastColumn = lastDimContainer.Column;
|
||||||
|
lastDimContainer.RequestScroll?.Invoke(lastDimContainer);
|
||||||
|
});
|
||||||
|
AddUntilStep("column undimmed", () => lastColumn.Active.Value);
|
||||||
|
|
||||||
|
AddStep("click panel", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(lastColumn.ChildrenOfType<ModPanel>().First());
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddUntilStep("panel selected", () => lastColumn.ChildrenOfType<ModPanel>().First().Active.Value);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCustomisationToggleState()
|
public void TestCustomisationToggleState()
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
[*.cs]
|
[*.cs]
|
||||||
|
dotnet_diagnostic.OLOC001.words_in_name = 5
|
||||||
dotnet_diagnostic.OLOC001.prefix_namespace = osu.Game.Resources.Localisation
|
dotnet_diagnostic.OLOC001.prefix_namespace = osu.Game.Resources.Localisation
|
||||||
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.
|
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\n// See the LICENCE file in the repository root for full licence text.
|
||||||
|
339
osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs
Normal file
339
osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
// 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 System.Text.RegularExpressions;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Utils;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
|
{
|
||||||
|
public class BundledBeatmapDownloader : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly bool shouldPostNotifications;
|
||||||
|
|
||||||
|
public IEnumerable<BeatmapDownloadTracker> DownloadTrackers => downloadTrackers;
|
||||||
|
|
||||||
|
private readonly List<BeatmapDownloadTracker> downloadTrackers = new List<BeatmapDownloadTracker>();
|
||||||
|
|
||||||
|
private readonly List<string> downloadableFilenames = new List<string>();
|
||||||
|
|
||||||
|
private BundledBeatmapModelDownloader beatmapDownloader;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Construct a new beatmap downloader.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="onlyTutorial">Whether only the tutorial should be downloaded, instead of bundled beatmaps.</param>
|
||||||
|
/// <param name="shouldPostNotifications">Whether downloads should create tracking notifications.</param>
|
||||||
|
public BundledBeatmapDownloader(bool onlyTutorial, bool shouldPostNotifications = false)
|
||||||
|
{
|
||||||
|
this.shouldPostNotifications = shouldPostNotifications;
|
||||||
|
|
||||||
|
if (onlyTutorial)
|
||||||
|
{
|
||||||
|
queueDownloads(new[] { tutorial_filename });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queueDownloads(always_bundled_beatmaps);
|
||||||
|
|
||||||
|
queueDownloads(bundled_osu, 8);
|
||||||
|
queueDownloads(bundled_taiko, 3);
|
||||||
|
queueDownloads(bundled_catch, 3);
|
||||||
|
queueDownloads(bundled_mania, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var localDependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
|
localDependencies.CacheAs<BeatmapModelDownloader>(beatmapDownloader = new BundledBeatmapModelDownloader(parent.Get<BeatmapManager>(), parent.Get<IAPIProvider>()));
|
||||||
|
|
||||||
|
if (shouldPostNotifications && parent.Get<INotificationOverlay>() is INotificationOverlay notifications)
|
||||||
|
beatmapDownloader.PostNotification = notifications.Post;
|
||||||
|
|
||||||
|
return localDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
foreach (string filename in downloadableFilenames)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(filename, @"([0-9]*) (.*) - (.*)\.osz");
|
||||||
|
|
||||||
|
var beatmapSet = new APIBeatmapSet
|
||||||
|
{
|
||||||
|
OnlineID = int.Parse(match.Groups[1].Value),
|
||||||
|
Artist = match.Groups[2].Value,
|
||||||
|
Title = match.Groups[3].Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
var beatmapDownloadTracker = new BeatmapDownloadTracker(beatmapSet);
|
||||||
|
downloadTrackers.Add(beatmapDownloadTracker);
|
||||||
|
AddInternal(beatmapDownloadTracker);
|
||||||
|
|
||||||
|
beatmapDownloader.Download(beatmapSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void queueDownloads(string[] sourceFilenames, int? limit = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Matches osu-stable, in order to provide new users with roughly the same randomised selection of bundled beatmaps.
|
||||||
|
var random = new LegacyRandom(DateTime.UtcNow.Year * 1000 + (DateTime.UtcNow.DayOfYear / 7));
|
||||||
|
|
||||||
|
downloadableFilenames.AddRange(sourceFilenames.OrderBy(x => random.NextDouble()).Take(limit ?? int.MaxValue));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BundledBeatmapModelDownloader : BeatmapModelDownloader
|
||||||
|
{
|
||||||
|
public BundledBeatmapModelDownloader(IModelImporter<BeatmapSetInfo> beatmapImporter, IAPIProvider api)
|
||||||
|
: base(beatmapImporter, api)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ArchiveDownloadRequest<IBeatmapSetInfo> CreateDownloadRequest(IBeatmapSetInfo set, bool minimiseDownloadSize)
|
||||||
|
=> new BundledBeatmapDownloadRequest(set, minimiseDownloadSize);
|
||||||
|
|
||||||
|
public class BundledBeatmapDownloadRequest : DownloadBeatmapSetRequest
|
||||||
|
{
|
||||||
|
protected override string Uri => $"https://assets.ppy.sh/client-resources/bundled/{Model.OnlineID}.osz";
|
||||||
|
|
||||||
|
public BundledBeatmapDownloadRequest(IBeatmapSetInfo beatmapSetInfo, bool minimiseDownloadSize)
|
||||||
|
: base(beatmapSetInfo, minimiseDownloadSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string tutorial_filename = "1011011 nekodex - new beginnings.osz";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contest winners or other special cases.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly string[] always_bundled_beatmaps =
|
||||||
|
{
|
||||||
|
// This thing is 40mb, I'm not sure we want it here...
|
||||||
|
@"1388906 Raphlesia & BilliumMoto - My Love.osz"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] bundled_osu =
|
||||||
|
{
|
||||||
|
"682286 Yuyoyuppe - Emerald Galaxy.osz",
|
||||||
|
"682287 baker - For a Dead Girl+.osz",
|
||||||
|
"682289 Hige Driver - I Wanna Feel Your Love (feat. shully).osz",
|
||||||
|
"682290 Hige Driver - Miracle Sugite Yabai (feat. shully).osz",
|
||||||
|
"682416 Hige Driver - Palette.osz",
|
||||||
|
"682595 baker - Kimi ga Kimi ga -vocanico remix-.osz",
|
||||||
|
"716211 yuki. - Spring Signal.osz",
|
||||||
|
"716213 dark cat - BUBBLE TEA (feat. juu & cinders).osz",
|
||||||
|
"716215 LukHash - CLONED.osz",
|
||||||
|
"716219 IAHN - Snowdrop.osz",
|
||||||
|
"716249 *namirin - Senaka Awase no Kuukyo (with Kakichoco).osz",
|
||||||
|
"716390 sakuraburst - SHA.osz",
|
||||||
|
"716441 Fractal Dreamers - Paradigm Shift.osz",
|
||||||
|
"729808 Thaehan - Leprechaun.osz",
|
||||||
|
"751771 Cranky - Hanaarashi.osz",
|
||||||
|
"751772 Cranky - Ran.osz",
|
||||||
|
"751773 Cranky - Feline, the White....osz",
|
||||||
|
"751774 Function Phantom - Variable.osz",
|
||||||
|
"751779 Rin - Daishibyo set 14 ~ Sado no Futatsuiwa.osz",
|
||||||
|
"751782 Fractal Dreamers - Fata Morgana.osz",
|
||||||
|
"751785 Cranky - Chandelier - King.osz",
|
||||||
|
"751846 Fractal Dreamers - Celestial Horizon.osz",
|
||||||
|
"751866 Rin - Moriya set 08 ReEdit ~ Youkai no Yama.osz",
|
||||||
|
"751894 Fractal Dreamers - Blue Haven.osz",
|
||||||
|
"751896 Cranky - Rave 2 Rave.osz",
|
||||||
|
"751932 Cranky - La fuite des jours.osz",
|
||||||
|
"751972 Cranky - CHASER.osz",
|
||||||
|
"779173 Thaehan - Superpower.osz",
|
||||||
|
"780932 VINXIS - A Centralized View.osz",
|
||||||
|
"785572 S3RL - I'll See You Again (feat. Chi Chi).osz",
|
||||||
|
"785650 yuki. feat. setsunan - Hello! World.osz",
|
||||||
|
"785677 Dictate - Militant.osz",
|
||||||
|
"785731 S3RL - Catchit (Radio Edit).osz",
|
||||||
|
"785774 LukHash - GLITCH.osz",
|
||||||
|
"786498 Trial & Error - Tokoyami no keiyaku KEGARETA-SHOUJO feat. GUMI.osz",
|
||||||
|
"789374 Pulse - LP.osz",
|
||||||
|
"789528 James Portland - Sky.osz",
|
||||||
|
"789529 Lexurus - Gravity.osz",
|
||||||
|
"789544 Andromedik - Invasion.osz",
|
||||||
|
"789905 Gourski x Himmes - Silence.osz",
|
||||||
|
"791667 cYsmix - Babaroque (Short Ver.).osz",
|
||||||
|
"791798 cYsmix - Behind the Walls.osz",
|
||||||
|
"791845 cYsmix - Little Knight.osz",
|
||||||
|
"792241 cYsmix - Eden.osz",
|
||||||
|
"792396 cYsmix - The Ballad of a Mindless Girl.osz",
|
||||||
|
"795432 Phonetic - Journey.osz",
|
||||||
|
"831322 DJ'TEKINA//SOMETHING - Hidamari no Uta.osz",
|
||||||
|
"847764 Cranky - Crocus.osz",
|
||||||
|
"847776 Culprate & Joe Ford - Gaucho.osz",
|
||||||
|
"847812 J. Pachelbel - Canon (Cranky Remix).osz",
|
||||||
|
"847900 Cranky - Time Alter.osz",
|
||||||
|
"847930 LukHash - 8BIT FAIRY TALE.osz",
|
||||||
|
"848003 Culprate - Aurora.osz",
|
||||||
|
"848068 nanobii - popsicle beach.osz",
|
||||||
|
"848090 Trial & Error - DAI*TAN SENSATION feat. Nanahira, Mii, Aitsuki Nakuru (Short Ver.).osz",
|
||||||
|
"848259 Culprate & Skorpion - Jester.osz",
|
||||||
|
"848976 Dictate - Treason.osz",
|
||||||
|
"851543 Culprate - Florn.osz",
|
||||||
|
"864748 Thaehan - Angry Birds Epic (Remix).osz",
|
||||||
|
"873667 OISHII - ONIGIRI FREEWAY.osz",
|
||||||
|
"876227 Culprate, Keota & Sophie Meiers - Mechanic Heartbeat.osz",
|
||||||
|
"880487 cYsmix - Peer Gynt.osz",
|
||||||
|
"883088 Wisp X - Somewhere I'd Rather Be.osz",
|
||||||
|
"891333 HyuN - White Aura.osz",
|
||||||
|
"891334 HyuN - Wild Card.osz",
|
||||||
|
"891337 HyuN feat. LyuU - Cross Over.osz",
|
||||||
|
"891338 HyuN & Ritoru - Apocalypse in Love.osz",
|
||||||
|
"891339 HyuN feat. Ato - Asu wa Ame ga Yamukara.osz",
|
||||||
|
"891345 HyuN - Infinity Heaven.osz",
|
||||||
|
"891348 HyuN - Guitian.osz",
|
||||||
|
"891356 HyuN - Legend of Genesis.osz",
|
||||||
|
"891366 HyuN - Illusion of Inflict.osz",
|
||||||
|
"891417 HyuN feat. Yu-A - My life is for you.osz",
|
||||||
|
"891441 HyuN - You'Re aRleAdY dEAd.osz",
|
||||||
|
"891632 HyuN feat. YURI - Disorder.osz",
|
||||||
|
"891712 HyuN - Tokyo's Starlight.osz",
|
||||||
|
"901091 *namirin - Ciel etoile.osz",
|
||||||
|
"916990 *namirin - Koishiteiku Planet.osz",
|
||||||
|
"929284 tieff - Sense of Nostalgia.osz",
|
||||||
|
"933940 Ben Briggs - Yes (Maybe).osz",
|
||||||
|
"934415 Ben Briggs - Fearless Living.osz",
|
||||||
|
"934627 Ben Briggs - New Game Plus.osz",
|
||||||
|
"934666 Ben Briggs - Wave Island.osz",
|
||||||
|
"936126 siromaru + cranky - conflict.osz",
|
||||||
|
"940377 onumi - ARROGANCE.osz",
|
||||||
|
"940597 tieff - Take Your Swimsuit.osz",
|
||||||
|
"941085 tieff - Our Story.osz",
|
||||||
|
"949297 tieff - Sunflower.osz",
|
||||||
|
"952380 Ben Briggs - Why Are We Yelling.osz",
|
||||||
|
"954272 *namirin - Kanzen Shouri*Esper Girl.osz",
|
||||||
|
"955866 KIRA & Heartbreaker - B.B.F (feat. Hatsune Miku & Kagamine Rin).osz",
|
||||||
|
"961320 Kuba Oms - All In All.osz",
|
||||||
|
"964553 The Flashbulb - You Take the World's Weight Away.osz",
|
||||||
|
"965651 Fractal Dreamers - Ad Astra.osz",
|
||||||
|
"966225 The Flashbulb - Passage D.osz",
|
||||||
|
"966324 DJ'TEKINA//SOMETHING - Hidamari no Uta.osz",
|
||||||
|
"972810 James Landino & Kabuki - Birdsong.osz",
|
||||||
|
"972932 James Landino - Hide And Seek.osz",
|
||||||
|
"977276 The Flashbulb - Mellann.osz",
|
||||||
|
"981616 *namirin - Mizutamari Tobikoete (with Nanahira).osz",
|
||||||
|
"985788 Loki - Wizard's Tower.osz",
|
||||||
|
"996628 OISHII - ONIGIRI FREEWAY.osz",
|
||||||
|
"996898 HyuN - White Aura.osz",
|
||||||
|
"1003554 yuki. - Nadeshiko Sensation.osz",
|
||||||
|
"1014936 Thaehan - Bwa !.osz",
|
||||||
|
"1019827 UNDEAD CORPORATION - Sad Dream.osz",
|
||||||
|
"1020213 Creo - Idolize.osz",
|
||||||
|
"1021450 Thaehan - Chiptune & Baroque.osz",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] bundled_taiko =
|
||||||
|
{
|
||||||
|
"707824 Fractal Dreamers - Fortuna Redux.osz",
|
||||||
|
"789553 Cranky - Ran.osz",
|
||||||
|
"827822 Function Phantom - Neuronecia.osz",
|
||||||
|
"847323 Nakanojojo - Bittersweet (feat. Kuishinboakachan a.k.a Kiato).osz",
|
||||||
|
"847433 Trial & Error - Tokoyami no keiyaku KEGARETA-SHOUJO feat. GUMI.osz",
|
||||||
|
"847576 dark cat - hot chocolate.osz",
|
||||||
|
"847957 Wisp X - Final Moments.osz",
|
||||||
|
"876282 VINXIS - Greetings.osz",
|
||||||
|
"876648 Thaehan - Angry Birds Epic (Remix).osz",
|
||||||
|
"877069 IAHN - Transform (Original Mix).osz",
|
||||||
|
"877496 Thaehan - Leprechaun.osz",
|
||||||
|
"877935 Thaehan - Overpowered.osz",
|
||||||
|
"878344 yuki. - Be Your Light.osz",
|
||||||
|
"918446 VINXIS - Facade.osz",
|
||||||
|
"918903 LukHash - Ghosts.osz",
|
||||||
|
"919251 *namirin - Hitokoto no Kyori.osz",
|
||||||
|
"919704 S3RL - I Will Pick You Up (feat. Tamika).osz",
|
||||||
|
"921535 SOOOO - Raven Haven.osz",
|
||||||
|
"927206 *namirin - Kanzen Shouri*Esper Girl.osz",
|
||||||
|
"927544 Camellia feat. Nanahira - Kansoku Eisei.osz",
|
||||||
|
"930806 Nakanojojo - Pararara (feat. Amekoya).osz",
|
||||||
|
"931741 Camellia - Quaoar.osz",
|
||||||
|
"935699 Rin - Mythic set ~ Heart-Stirring Urban Legends.osz",
|
||||||
|
"935732 Thaehan - Yuujou.osz",
|
||||||
|
"941145 Function Phantom - Euclid.osz",
|
||||||
|
"942334 Dictate - Cauldron.osz",
|
||||||
|
"946540 nanobii - astral blast.osz",
|
||||||
|
"948844 Rin - Kishinjou set 01 ~ Mist Lake.osz",
|
||||||
|
"949122 Wisp X - Petal.osz",
|
||||||
|
"951618 Rin - Kishinjou set 02 ~ Mermaid from the Uncharted Land.osz",
|
||||||
|
"957412 Rin - Lunatic set 16 ~ The Space Shrine Maiden Returns Home.osz",
|
||||||
|
"961335 Thaehan - Insert Coin.osz",
|
||||||
|
"965178 The Flashbulb - DIDJ PVC.osz",
|
||||||
|
"966087 The Flashbulb - Creep.osz",
|
||||||
|
"966277 The Flashbulb - Amen Iraq.osz",
|
||||||
|
"966407 LukHash - ROOM 12.osz",
|
||||||
|
"966451 The Flashbulb - Six Acid Strings.osz",
|
||||||
|
"972301 BilliumMoto - four veiled stars.osz",
|
||||||
|
"973173 nanobii - popsicle beach.osz",
|
||||||
|
"973954 BilliumMoto - Rocky Buinne (Short Ver.).osz",
|
||||||
|
"975435 BilliumMoto - life flashes before weeb eyes.osz",
|
||||||
|
"978759 L. V. Beethoven - Moonlight Sonata (Cranky Remix).osz",
|
||||||
|
"982559 BilliumMoto - HDHR.osz",
|
||||||
|
"984361 The Flashbulb - Ninedump.osz",
|
||||||
|
"1023681 Inferi - The Ruin of Mankind.osz",
|
||||||
|
"1034358 ALEPH - The Evil Spirit.osz",
|
||||||
|
"1037567 ALEPH - Scintillations.osz",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] bundled_catch =
|
||||||
|
{
|
||||||
|
"554256 Helblinde - When Time Sleeps.osz",
|
||||||
|
"693123 yuki. - Nadeshiko Sensation.osz",
|
||||||
|
"767009 OISHII - PIZZA PLAZA.osz",
|
||||||
|
"767346 Thaehan - Bwa !.osz",
|
||||||
|
"815162 VINXIS - Greetings.osz",
|
||||||
|
"840964 cYsmix - Breeze.osz",
|
||||||
|
"932657 Wisp X - Eventide.osz",
|
||||||
|
"933700 onumi - CONFUSION PART ONE.osz",
|
||||||
|
"933984 onumi - PERSONALITY.osz",
|
||||||
|
"934785 onumi - FAKE.osz",
|
||||||
|
"936545 onumi - REGRET PART ONE.osz",
|
||||||
|
"943803 Fractal Dreamers - Everything for a Dream.osz",
|
||||||
|
"943876 S3RL - I Will Pick You Up (feat. Tamika).osz",
|
||||||
|
"946773 Trial & Error - DREAMING COLOR (Short Ver.).osz",
|
||||||
|
"955808 Trial & Error - Tokoyami no keiyaku KEGARETA-SHOUJO feat. GUMI (Short Ver.).osz",
|
||||||
|
"957808 Fractal Dreamers - Module_410.osz",
|
||||||
|
"957842 antiPLUR - One Life Left to Live.osz",
|
||||||
|
"965730 The Flashbulb - Lawn Wake IV (Black).osz",
|
||||||
|
"966240 Creo - Challenger.osz",
|
||||||
|
"968232 Rin - Lunatic set 15 ~ The Moon as Seen from the Shrine.osz",
|
||||||
|
"972302 VINXIS - A Centralized View.osz",
|
||||||
|
"972887 HyuN - Illusion of Inflict.osz",
|
||||||
|
"1008600 LukHash - WHEN AN ANGEL DIES.osz",
|
||||||
|
"1032103 LukHash - H8 U.osz",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] bundled_mania =
|
||||||
|
{
|
||||||
|
"943516 antiPLUR - Clockwork Spooks.osz",
|
||||||
|
"946394 VINXIS - Three Times The Original Charm.osz",
|
||||||
|
"966408 antiPLUR - One Life Left to Live.osz",
|
||||||
|
"971561 antiPLUR - Runengon.osz",
|
||||||
|
"983864 James Landino - Shiba Island.osz",
|
||||||
|
"989512 BilliumMoto - 1xMISS.osz",
|
||||||
|
"994104 James Landino - Reaction feat. Slyleaf.osz",
|
||||||
|
"1003217 nekodex - circles!.osz",
|
||||||
|
"1009907 James Landino & Kabuki - Birdsong.osz",
|
||||||
|
"1015169 Thaehan - Insert Coin.osz",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -28,11 +28,6 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
},
|
},
|
||||||
downloadTracker = new BeatmapDownloadTracker(beatmapSet),
|
downloadTracker = new BeatmapDownloadTracker(beatmapSet),
|
||||||
};
|
};
|
||||||
AddInternal(progressBar = new ProgressBar(false)
|
|
||||||
{
|
|
||||||
Height = 0,
|
|
||||||
Alpha = 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
@ -42,12 +43,12 @@ namespace osu.Game.Extensions
|
|||||||
public static LocalisableString ToFormattedDuration(this TimeSpan timeSpan)
|
public static LocalisableString ToFormattedDuration(this TimeSpan timeSpan)
|
||||||
{
|
{
|
||||||
if (timeSpan.TotalDays >= 1)
|
if (timeSpan.TotalDays >= 1)
|
||||||
return new LocalisableFormattableString(timeSpan, @"dd\:hh\:mm\:ss");
|
return timeSpan.ToLocalisableString(@"dd\:hh\:mm\:ss");
|
||||||
|
|
||||||
if (timeSpan.TotalHours >= 1)
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -57,6 +58,26 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scrolls a <see cref="Drawable"/> into view.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="d">The <see cref="Drawable"/> to scroll into view.</param>
|
||||||
|
/// <param name="animated">Whether to animate the movement.</param>
|
||||||
|
/// <param name="extraScroll">An added amount to scroll beyond the requirement to bring the target into view.</param>
|
||||||
|
public void ScrollIntoView(Drawable d, bool animated = true, float extraScroll = 0)
|
||||||
|
{
|
||||||
|
float childPos0 = GetChildPosInContent(d);
|
||||||
|
float childPos1 = GetChildPosInContent(d, d.DrawSize);
|
||||||
|
|
||||||
|
float minPos = Math.Min(childPos0, childPos1);
|
||||||
|
float maxPos = Math.Max(childPos0, childPos1);
|
||||||
|
|
||||||
|
if (minPos < Current || (minPos > Current && d.DrawSize[ScrollDim] > DisplayableContent))
|
||||||
|
ScrollTo(minPos - extraScroll, animated);
|
||||||
|
else if (maxPos > Current + DisplayableContent)
|
||||||
|
ScrollTo(maxPos - DisplayableContent + extraScroll, animated);
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
{
|
{
|
||||||
if (shouldPerformRightMouseScroll(e))
|
if (shouldPerformRightMouseScroll(e))
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -131,22 +130,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
BackgroundColourSelected = SelectionColour
|
BackgroundColourSelected = SelectionColour
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override ScrollContainer<Drawable> CreateScrollContainer(Direction direction) => new DropdownScrollContainer(direction);
|
protected override ScrollContainer<Drawable> CreateScrollContainer(Direction direction) => new OsuScrollContainer(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region DrawableOsuDropdownMenuItem
|
#region DrawableOsuDropdownMenuItem
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -82,22 +81,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
return new DrawableOsuMenuItem(item);
|
return new DrawableOsuMenuItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ScrollContainer<Drawable> CreateScrollContainer(Direction direction) => new OsuMenuScrollContainer(direction);
|
protected override ScrollContainer<Drawable> CreateScrollContainer(Direction direction) => new OsuScrollContainer(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 Menu CreateSubMenu() => new OsuMenu(Direction.Vertical)
|
protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical)
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterfaceV2
|
namespace osu.Game.Graphics.UserInterfaceV2
|
||||||
{
|
{
|
||||||
@ -28,7 +29,8 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load([CanBeNull] OverlayColourProvider overlayColourProvider, OsuColour colours)
|
private void load([CanBeNull] OverlayColourProvider overlayColourProvider, OsuColour colours)
|
||||||
{
|
{
|
||||||
BackgroundColour = overlayColourProvider?.Highlight1 ?? colours.Blue3;
|
if (BackgroundColour == Color4.White)
|
||||||
|
BackgroundColour = overlayColourProvider?.Highlight1 ?? colours.Blue3;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
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.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -31,6 +33,9 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
private Color4 enabledColour;
|
private Color4 enabledColour;
|
||||||
private Color4 disabledColour;
|
private Color4 disabledColour;
|
||||||
|
|
||||||
|
private Sample? sampleChecked;
|
||||||
|
private Sample? sampleUnchecked;
|
||||||
|
|
||||||
public SwitchButton()
|
public SwitchButton()
|
||||||
{
|
{
|
||||||
Size = new Vector2(45, 20);
|
Size = new Vector2(45, 20);
|
||||||
@ -70,13 +75,16 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OverlayColourProvider? colourProvider, OsuColour colours)
|
private void load(OverlayColourProvider? colourProvider, OsuColour colours, AudioManager audio)
|
||||||
{
|
{
|
||||||
enabledColour = colourProvider?.Highlight1 ?? colours.BlueDark;
|
enabledColour = colourProvider?.Highlight1 ?? colours.BlueDark;
|
||||||
disabledColour = colourProvider?.Background3 ?? colours.Gray3;
|
disabledColour = colourProvider?.Background3 ?? colours.Gray3;
|
||||||
|
|
||||||
switchContainer.Colour = enabledColour;
|
switchContainer.Colour = enabledColour;
|
||||||
fill.Colour = disabledColour;
|
fill.Colour = disabledColour;
|
||||||
|
|
||||||
|
sampleChecked = audio.Samples.Get(@"UI/check-on");
|
||||||
|
sampleUnchecked = audio.Samples.Get(@"UI/check-off");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -107,6 +115,16 @@ namespace osu.Game.Graphics.UserInterfaceV2
|
|||||||
base.OnHoverLost(e);
|
base.OnHoverLost(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnUserChange(bool value)
|
||||||
|
{
|
||||||
|
base.OnUserChange(value);
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
sampleChecked?.Play();
|
||||||
|
else
|
||||||
|
sampleUnchecked?.Play();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBorder()
|
private void updateBorder()
|
||||||
{
|
{
|
||||||
circularContainer.TransformBorderTo((Current.Value ? enabledColour : disabledColour).Lighten(IsHovered ? 0.3f : 0));
|
circularContainer.TransformBorderTo((Current.Value ? enabledColour : disabledColour).Lighten(IsHovered ? 0.3f : 0));
|
||||||
|
54
osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs
Normal file
54
osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// 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 osu.Framework.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class FirstRunSetupBeatmapScreenStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.FirstRunSetupBeatmapScreen";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Obtaining Beatmaps"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Header => new TranslatableString(getKey(@"header"), @"Obtaining Beatmaps");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ""Beatmaps" are what we call playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"""Beatmaps"" are what we call playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "If you are a new player, we recommend playing through the tutorial to get accustomed to the gameplay."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TutorialDescription => new TranslatableString(getKey(@"tutorial_description"), @"If you are a new player, we recommend playing through the tutorial to get accustomed to the gameplay.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Get the osu! tutorial"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TutorialButton => new TranslatableString(getKey(@"tutorial_button"), @"Get the osu! tutorial");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "To get you started, we have some recommended beatmaps."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BundledDescription => new TranslatableString(getKey(@"bundled_description"), @"To get you started, we have some recommended beatmaps.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Get recommended beatmaps"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BundledButton => new TranslatableString(getKey(@"bundled_button"), @"Get recommended beatmaps");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "You can also obtain more beatmaps from the main menu "browse" button at any time."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ObtainMoreBeatmaps => new TranslatableString(getKey(@"obtain_more_beatmaps"), @"You can also obtain more beatmaps from the main menu ""browse"" button at any time.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "You currently have {0} beatmap(s) loaded!"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CurrentlyLoadedBeatmaps(int beatmaps) => new TranslatableString(getKey(@"currently_loaded_beatmaps"), @"You currently have {0} beatmap(s) loaded!", beatmaps);
|
||||||
|
|
||||||
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,8 @@ namespace osu.Game.Localisation
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Click to resume first-run setup at any point"
|
/// "Click to resume first-run setup at any point"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString ClickToResumeFirstRunSetupAtAnyPoint => new TranslatableString(getKey(@"click_to_resume_first_run_setup_at_any_point"), @"Click to resume first-run setup at any point");
|
public static LocalisableString ClickToResumeFirstRunSetupAtAnyPoint =>
|
||||||
|
new TranslatableString(getKey(@"click_to_resume_first_run_setup_at_any_point"), @"Click to resume first-run setup at any point");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "First-run setup"
|
/// "First-run setup"
|
||||||
@ -48,6 +49,31 @@ osu! is a very configurable game, and diving straight into the settings can some
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString UIScaleDescription => new TranslatableString(getKey(@"ui_scale_description"), @"The size of the osu! user interface can be adjusted to your liking.");
|
public static LocalisableString UIScaleDescription => new TranslatableString(getKey(@"ui_scale_description"), @"The size of the osu! user interface can be adjusted to your liking.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Behaviour"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Behaviour => new TranslatableString(getKey(@"behaviour"), @"Behaviour");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Some new defaults for game behaviours have been implemented, with the aim of improving the game experience and making it more accessible to everyone.
|
||||||
|
///
|
||||||
|
/// We recommend you give the new defaults a try, but if you'd like to have things feel more like classic versions of osu!, you can easily apply some sane defaults below."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BehaviourDescription => new TranslatableString(getKey(@"behaviour_description"),
|
||||||
|
@"Some new defaults for game behaviours have been implemented, with the aim of improving the game experience and making it more accessible to everyone.
|
||||||
|
|
||||||
|
We recommend you give the new defaults a try, but if you'd like to have things feel more like classic versions of osu!, you can easily apply some sane defaults below.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "New defaults"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NewDefaults => new TranslatableString(getKey(@"new_defaults"), @"New defaults");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Classic defaults"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ClassicDefaults => new TranslatableString(getKey(@"classic_defaults"), @"Classic defaults");
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
Size = new Vector2(12),
|
Size = new Vector2(12),
|
||||||
Icon = getIconForCardSize(Value)
|
Icon = getIconForCardSize(Value)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
new HoverClickSounds(HoverSampleSet.TabSelect)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
maxComboColumn.Text = value.MaxCombo.ToLocalisableString(@"0\x");
|
maxComboColumn.Text = value.MaxCombo.ToLocalisableString(@"0\x");
|
||||||
|
|
||||||
ppColumn.Alpha = value.BeatmapInfo.Status.GrantsPerformancePoints() ? 1 : 0;
|
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);
|
statisticsColumns.ChildrenEnumerable = value.GetStatisticsForDisplay().Select(createStatisticsColumn);
|
||||||
modsColumn.Mods = value.Mods;
|
modsColumn.Mods = value.Mods;
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.FirstRunSetup
|
namespace osu.Game.Overlays.FirstRunSetup
|
||||||
@ -15,19 +19,37 @@ namespace osu.Game.Overlays.FirstRunSetup
|
|||||||
|
|
||||||
protected FillFlowContainer Content { get; private set; }
|
protected FillFlowContainer Content { get; private set; }
|
||||||
|
|
||||||
protected FirstRunSetupScreen()
|
[Resolved]
|
||||||
|
protected OverlayColourProvider OverlayColourProvider { get; private set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
|
const float header_size = 40;
|
||||||
|
const float spacing = 20;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuScrollContainer(Direction.Vertical)
|
new OsuScrollContainer(Direction.Vertical)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = Content = new FillFlowContainer
|
ScrollbarOverlapsContent = false,
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
Spacing = new Vector2(20),
|
new OsuSpriteText
|
||||||
RelativeSizeAxes = Axes.X,
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
Text = this.GetLocalisableDescription(),
|
||||||
Direction = FillDirection.Vertical,
|
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,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
258
osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs
Normal file
258
osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osuTK;
|
||||||
|
using Realms;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.FirstRunSetup
|
||||||
|
{
|
||||||
|
[LocalisableDescription(typeof(FirstRunSetupBeatmapScreenStrings), nameof(FirstRunSetupBeatmapScreenStrings.Header))]
|
||||||
|
public class ScreenBeatmaps : FirstRunSetupScreen
|
||||||
|
{
|
||||||
|
private ProgressRoundedButton downloadBundledButton = null!;
|
||||||
|
private ProgressRoundedButton importBeatmapsButton = null!;
|
||||||
|
private ProgressRoundedButton downloadTutorialButton = null!;
|
||||||
|
|
||||||
|
private OsuTextFlowContainer currentlyLoadedBeatmaps = null!;
|
||||||
|
|
||||||
|
private BundledBeatmapDownloader? tutorialDownloader;
|
||||||
|
private BundledBeatmapDownloader? bundledDownloader;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RealmAccess realmAccess { get; set; } = null!;
|
||||||
|
|
||||||
|
private IDisposable? beatmapSubscription;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
|
private void load(LegacyImportManager? legacyImportManager)
|
||||||
|
{
|
||||||
|
Vector2 buttonSize = new Vector2(500, 60);
|
||||||
|
|
||||||
|
Content.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content1,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.Description,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 30,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
currentlyLoadedBeatmaps = new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 24, weight: FontWeight.SemiBold))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content2,
|
||||||
|
TextAnchor = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content1,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.TutorialDescription,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
downloadTutorialButton = new ProgressRoundedButton
|
||||||
|
{
|
||||||
|
Size = buttonSize,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
BackgroundColour = colours.Pink3,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.TutorialButton,
|
||||||
|
Action = downloadTutorial
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content1,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.BundledDescription,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
downloadBundledButton = new ProgressRoundedButton
|
||||||
|
{
|
||||||
|
Size = buttonSize,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
BackgroundColour = colours.Blue3,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.BundledButton,
|
||||||
|
Action = downloadBundled
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content1,
|
||||||
|
Text = "If you have an existing osu! install, you can also choose to import your existing beatmap collection.",
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
importBeatmapsButton = new ProgressRoundedButton
|
||||||
|
{
|
||||||
|
Size = buttonSize,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
BackgroundColour = colours.Blue3,
|
||||||
|
Text = MaintenanceSettingsStrings.ImportBeatmapsFromStable,
|
||||||
|
Action = () =>
|
||||||
|
{
|
||||||
|
importBeatmapsButton.Enabled.Value = false;
|
||||||
|
legacyImportManager?.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(t => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
importBeatmapsButton.Complete();
|
||||||
|
else
|
||||||
|
importBeatmapsButton.Enabled.Value = true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
|
||||||
|
{
|
||||||
|
Colour = OverlayColourProvider.Content1,
|
||||||
|
Text = FirstRunSetupBeatmapScreenStrings.ObtainMoreBeatmaps,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
beatmapSubscription = realmAccess.RegisterForNotifications(r => r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
beatmapSubscription?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes, Exception error)
|
||||||
|
{
|
||||||
|
currentlyLoadedBeatmaps.Text = FirstRunSetupBeatmapScreenStrings.CurrentlyLoadedBeatmaps(sender.Count);
|
||||||
|
|
||||||
|
if (sender.Count == 0)
|
||||||
|
{
|
||||||
|
currentlyLoadedBeatmaps.FadeColour(colours.Red1, 500, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
else if (changes != null && (changes.DeletedIndices.Any() || changes.InsertedIndices.Any()))
|
||||||
|
{
|
||||||
|
currentlyLoadedBeatmaps.FadeColour(colours.Yellow)
|
||||||
|
.FadeColour(OverlayColourProvider.Content2, 1500, Easing.OutQuint);
|
||||||
|
|
||||||
|
currentlyLoadedBeatmaps.ScaleTo(1.1f)
|
||||||
|
.ScaleTo(1, 1500, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadTutorial()
|
||||||
|
{
|
||||||
|
if (tutorialDownloader != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tutorialDownloader = new BundledBeatmapDownloader(true);
|
||||||
|
|
||||||
|
AddInternal(tutorialDownloader);
|
||||||
|
|
||||||
|
var downloadTracker = tutorialDownloader.DownloadTrackers.First();
|
||||||
|
|
||||||
|
downloadTracker.Progress.BindValueChanged(progress =>
|
||||||
|
{
|
||||||
|
downloadTutorialButton.SetProgress(progress.NewValue, false);
|
||||||
|
|
||||||
|
if (progress.NewValue == 1)
|
||||||
|
downloadTutorialButton.Complete();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadBundled()
|
||||||
|
{
|
||||||
|
if (bundledDownloader != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bundledDownloader = new BundledBeatmapDownloader(false);
|
||||||
|
|
||||||
|
AddInternal(bundledDownloader);
|
||||||
|
|
||||||
|
foreach (var tracker in bundledDownloader.DownloadTrackers)
|
||||||
|
tracker.State.BindValueChanged(_ => updateProgress(), true);
|
||||||
|
|
||||||
|
void updateProgress()
|
||||||
|
{
|
||||||
|
double progress = (double)bundledDownloader.DownloadTrackers.Count(t => t.State.Value == DownloadState.LocallyAvailable) / bundledDownloader.DownloadTrackers.Count();
|
||||||
|
|
||||||
|
if (progress == 1)
|
||||||
|
downloadBundledButton.Complete();
|
||||||
|
else
|
||||||
|
downloadBundledButton.SetProgress(progress, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProgressRoundedButton : RoundedButton
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
|
private ProgressBar progressBar = null!;
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Add(progressBar = new ProgressBar(false)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
FillColour = BackgroundColour,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
Depth = float.MinValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Complete()
|
||||||
|
{
|
||||||
|
Enabled.Value = false;
|
||||||
|
|
||||||
|
Background.FadeColour(colours.Green, 500, Easing.OutQuint);
|
||||||
|
progressBar.FillColour = colours.Green;
|
||||||
|
|
||||||
|
this.TransformBindableTo(progressBar.Current, 1, 500, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetProgress(double progress, bool animated)
|
||||||
|
{
|
||||||
|
if (!Enabled.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.TransformBindableTo(progressBar.Current, progress, animated ? 500 : 0, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs
Normal file
109
osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// 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.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;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Overlays.Settings.Sections;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.FirstRunSetup
|
||||||
|
{
|
||||||
|
[LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.Behaviour))]
|
||||||
|
public class ScreenBehaviour : FirstRunSetupScreen
|
||||||
|
{
|
||||||
|
private SearchContainer<SettingsSection> searchContainer;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Content.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 24))
|
||||||
|
{
|
||||||
|
Text = FirstRunSetupOverlayStrings.BehaviourDescription,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
},
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
ColumnDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(),
|
||||||
|
new Dimension(GridSizeMode.Absolute, 10),
|
||||||
|
new Dimension(),
|
||||||
|
},
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
},
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new TriangleButton
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Text = FirstRunSetupOverlayStrings.NewDefaults,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Action = applyStandard,
|
||||||
|
},
|
||||||
|
Empty(),
|
||||||
|
new DangerousTriangleButton
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Text = FirstRunSetupOverlayStrings.ClassicDefaults,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Action = applyClassic
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchContainer = new SearchContainer<SettingsSection>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Children = new SettingsSection[]
|
||||||
|
{
|
||||||
|
// This list should be kept in sync with SettingsOverlay.
|
||||||
|
new GeneralSection(),
|
||||||
|
new SkinSection(),
|
||||||
|
// InputSection is intentionally omitted for now due to its sub-panel being a pain to set up.
|
||||||
|
new UserInterfaceSection(),
|
||||||
|
new GameplaySection(),
|
||||||
|
new RulesetSection(),
|
||||||
|
new AudioSection(),
|
||||||
|
new GraphicsSection(),
|
||||||
|
new OnlineSection(),
|
||||||
|
new MaintenanceSection(),
|
||||||
|
new DebugSection(),
|
||||||
|
},
|
||||||
|
SearchTerm = SettingsItem<bool>.CLASSIC_DEFAULT_SEARCH_TERM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyClassic()
|
||||||
|
{
|
||||||
|
foreach (var i in searchContainer.ChildrenOfType<ISettingsItem>().Where(s => s.HasClassicDefault))
|
||||||
|
i.ApplyClassicDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyStandard()
|
||||||
|
{
|
||||||
|
foreach (var i in searchContainer.ChildrenOfType<ISettingsItem>().Where(s => s.HasClassicDefault))
|
||||||
|
i.ApplyDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.FirstRunSetup
|
namespace osu.Game.Overlays.FirstRunSetup
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(GraphicsSettingsStrings), nameof(GraphicsSettingsStrings.UIScaling))]
|
||||||
public class ScreenUIScale : FirstRunSetupScreen
|
public class ScreenUIScale : FirstRunSetupScreen
|
||||||
{
|
{
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.FirstRunSetup
|
namespace osu.Game.Overlays.FirstRunSetup
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.WelcomeTitle))]
|
||||||
public class ScreenWelcome : FirstRunSetupScreen
|
public class ScreenWelcome : FirstRunSetupScreen
|
||||||
{
|
{
|
||||||
public ScreenWelcome()
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
Content.Children = new Drawable[]
|
Content.Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -56,10 +57,12 @@ namespace osu.Game.Overlays
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public FirstRunSetupScreen? CurrentScreen => (FirstRunSetupScreen?)stack?.CurrentScreen;
|
public FirstRunSetupScreen? CurrentScreen => (FirstRunSetupScreen?)stack?.CurrentScreen;
|
||||||
|
|
||||||
private readonly FirstRunStep[] steps =
|
private readonly Type[] steps =
|
||||||
{
|
{
|
||||||
new FirstRunStep(typeof(ScreenWelcome), FirstRunSetupOverlayStrings.WelcomeTitle),
|
typeof(ScreenWelcome),
|
||||||
new FirstRunStep(typeof(ScreenUIScale), GraphicsSettingsStrings.UIScaling),
|
typeof(ScreenBeatmaps),
|
||||||
|
typeof(ScreenUIScale),
|
||||||
|
typeof(ScreenBehaviour),
|
||||||
};
|
};
|
||||||
|
|
||||||
private Container stackContainer = null!;
|
private Container stackContainer = null!;
|
||||||
@ -81,7 +84,7 @@ namespace osu.Game.Overlays
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Horizontal = 50 },
|
Padding = new MarginPadding { Horizontal = 70 * 1.2f },
|
||||||
Child = new InputBlockingContainer
|
Child = new InputBlockingContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
@ -102,7 +105,7 @@ namespace osu.Game.Overlays
|
|||||||
Padding = new MarginPadding
|
Padding = new MarginPadding
|
||||||
{
|
{
|
||||||
Vertical = 20,
|
Vertical = 20,
|
||||||
Horizontal = 20,
|
Horizontal = 70,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -286,7 +289,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
if (currentStepIndex < steps.Length)
|
if (currentStepIndex < steps.Length)
|
||||||
{
|
{
|
||||||
stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value].ScreenType));
|
stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -317,23 +320,11 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
else
|
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
|
NextButton.Text = isLastStep
|
||||||
? CommonStrings.Finish
|
? CommonStrings.Finish
|
||||||
: new TranslatableString(@"_", @"{0} ({1})", CommonStrings.Next, steps[currentStepIndex.Value + 1].Description);
|
: LocalisableString.Interpolate($@"{CommonStrings.Next} ({steps[currentStepIndex.Value + 1].GetLocalisableDescription()})");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FirstRunStep
|
|
||||||
{
|
|
||||||
public readonly Type ScreenType;
|
|
||||||
public readonly LocalisableString Description;
|
|
||||||
|
|
||||||
public FirstRunStep(Type screenType, LocalisableString description)
|
|
||||||
{
|
|
||||||
ScreenType = screenType;
|
|
||||||
Description = description;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||||
|
public Bindable<bool> Active = new BindableBool(true);
|
||||||
|
|
||||||
|
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => base.ReceivePositionalInputAtSubTree(screenSpacePos) && Active.Value;
|
||||||
|
|
||||||
protected virtual ModPanel CreateModPanel(Mod mod) => new ModPanel(mod);
|
protected virtual ModPanel CreateModPanel(Mod mod) => new ModPanel(mod);
|
||||||
|
|
||||||
@ -441,7 +444,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
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;
|
if (toggleKeys == null) return false;
|
||||||
|
|
||||||
int index = Array.IndexOf(toggleKeys, e.Key);
|
int index = Array.IndexOf(toggleKeys, e.Key);
|
||||||
|
@ -13,7 +13,9 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Layout;
|
using osu.Framework.Layout;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -59,7 +61,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
private DifficultyMultiplierDisplay? multiplierDisplay;
|
private DifficultyMultiplierDisplay? multiplierDisplay;
|
||||||
private ModSettingsArea modSettingsArea = null!;
|
private ModSettingsArea modSettingsArea = null!;
|
||||||
private FillFlowContainer<ModColumn> columnFlow = null!;
|
private ColumnScrollContainer columnScroll = null!;
|
||||||
|
private ColumnFlowContainer columnFlow = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
@ -95,27 +98,27 @@ namespace osu.Game.Overlays.Mods
|
|||||||
RelativePositionAxes = Axes.Both,
|
RelativePositionAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuScrollContainer(Direction.Horizontal)
|
columnScroll = new ColumnScrollContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = false,
|
Masking = false,
|
||||||
ClampExtension = 100,
|
ClampExtension = 100,
|
||||||
ScrollbarOverlapsContent = false,
|
ScrollbarOverlapsContent = false,
|
||||||
Child = columnFlow = new ModColumnContainer
|
Child = columnFlow = new ColumnFlowContainer
|
||||||
{
|
{
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Shear = new Vector2(SHEAR, 0),
|
Shear = new Vector2(SHEAR, 0),
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
Spacing = new Vector2(10, 0),
|
Spacing = new Vector2(10, 0),
|
||||||
Margin = new MarginPadding { Right = 70 },
|
Margin = new MarginPadding { Horizontal = 70 },
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
CreateModColumn(ModType.DifficultyReduction, new[] { Key.Q, Key.W, Key.E, Key.R, Key.T, Key.Y, Key.U, Key.I, Key.O, Key.P }),
|
createModColumnContent(ModType.DifficultyReduction, new[] { Key.Q, Key.W, Key.E, Key.R, Key.T, Key.Y, Key.U, Key.I, Key.O, Key.P }),
|
||||||
CreateModColumn(ModType.DifficultyIncrease, new[] { Key.A, Key.S, Key.D, Key.F, Key.G, Key.H, Key.J, Key.K, Key.L }),
|
createModColumnContent(ModType.DifficultyIncrease, new[] { Key.A, Key.S, Key.D, Key.F, Key.G, Key.H, Key.J, Key.K, Key.L }),
|
||||||
CreateModColumn(ModType.Automation, new[] { Key.Z, Key.X, Key.C, Key.V, Key.B, Key.N, Key.M }),
|
createModColumnContent(ModType.Automation, new[] { Key.Z, Key.X, Key.C, Key.V, Key.B, Key.N, Key.M }),
|
||||||
CreateModColumn(ModType.Conversion),
|
createModColumnContent(ModType.Conversion),
|
||||||
CreateModColumn(ModType.Fun)
|
createModColumnContent(ModType.Fun)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,6 +156,14 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ColumnDimContainer createModColumnContent(ModType modType, Key[]? toggleKeys = null)
|
||||||
|
=> new ColumnDimContainer(CreateModColumn(modType, toggleKeys))
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
RequestScroll = column => columnScroll.ScrollIntoView(column, extraScroll: 140)
|
||||||
|
};
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -166,7 +177,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
updateSelectionFromBindable();
|
updateSelectionFromBindable();
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
foreach (var column in columnFlow)
|
foreach (var column in columnFlow.Columns)
|
||||||
{
|
{
|
||||||
column.SelectedMods.BindValueChanged(updateBindableFromSelection);
|
column.SelectedMods.BindValueChanged(updateBindableFromSelection);
|
||||||
}
|
}
|
||||||
@ -191,7 +202,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
private void updateAvailableMods()
|
private void updateAvailableMods()
|
||||||
{
|
{
|
||||||
foreach (var column in columnFlow)
|
foreach (var column in columnFlow.Columns)
|
||||||
column.Filter = isValidMod;
|
column.Filter = isValidMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +255,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
// to synchronise state correctly, updateBindableFromSelection() computes the final mods (including incompatibility rules) and updates SelectedMods,
|
// to synchronise state correctly, updateBindableFromSelection() computes the final mods (including incompatibility rules) and updates SelectedMods,
|
||||||
// and this method then runs unconditionally again to make sure the new visual selection accurately reflects the final set of selected mods.
|
// and this method then runs unconditionally again to make sure the new visual selection accurately reflects the final set of selected mods.
|
||||||
// selectionBindableSyncInProgress ensures that mutual infinite recursion does not happen after that unconditional call.
|
// selectionBindableSyncInProgress ensures that mutual infinite recursion does not happen after that unconditional call.
|
||||||
foreach (var column in columnFlow)
|
foreach (var column in columnFlow.Columns)
|
||||||
column.SelectedMods.Value = SelectedMods.Value.Where(mod => mod.Type == column.ModType).ToArray();
|
column.SelectedMods.Value = SelectedMods.Value.Where(mod => mod.Type == column.ModType).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +276,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IReadOnlyList<Mod> ComputeNewModsFromSelection(IEnumerable<Mod> addedMods, IEnumerable<Mod> removedMods)
|
protected virtual IReadOnlyList<Mod> ComputeNewModsFromSelection(IEnumerable<Mod> addedMods, IEnumerable<Mod> removedMods)
|
||||||
=> columnFlow.SelectMany(column => column.SelectedMods.Value).ToArray();
|
=> columnFlow.Columns.SelectMany(column => column.SelectedMods.Value).ToArray();
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
@ -280,7 +291,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
for (int i = 0; i < columnFlow.Count; i++)
|
for (int i = 0; i < columnFlow.Count; i++)
|
||||||
{
|
{
|
||||||
columnFlow[i].TopLevelContent
|
columnFlow[i].Column
|
||||||
|
.TopLevelContent
|
||||||
.Delay(i * 30)
|
.Delay(i * 30)
|
||||||
.MoveToY(0, fade_in_duration, Easing.OutQuint)
|
.MoveToY(0, fade_in_duration, Easing.OutQuint)
|
||||||
.FadeIn(fade_in_duration, Easing.OutQuint);
|
.FadeIn(fade_in_duration, Easing.OutQuint);
|
||||||
@ -301,27 +313,68 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
const float distance = 700;
|
const float distance = 700;
|
||||||
|
|
||||||
columnFlow[i].TopLevelContent
|
columnFlow[i].Column
|
||||||
|
.TopLevelContent
|
||||||
.MoveToY(i % 2 == 0 ? -distance : distance, fade_out_duration, Easing.OutQuint)
|
.MoveToY(i % 2 == 0 ? -distance : distance, fade_out_duration, Easing.OutQuint)
|
||||||
.FadeOut(fade_out_duration, Easing.OutQuint);
|
.FadeOut(fade_out_duration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ModColumnContainer : FillFlowContainer<ModColumn>
|
internal class ColumnScrollContainer : OsuScrollContainer<ColumnFlowContainer>
|
||||||
{
|
{
|
||||||
|
public ColumnScrollContainer()
|
||||||
|
: base(Direction.Horizontal)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
// the bounds below represent the horizontal range of scroll items to be considered fully visible/active, in the scroll's internal coordinate space.
|
||||||
|
// note that clamping is applied to the left scroll bound to ensure scrolling past extents does not change the set of active columns.
|
||||||
|
float leftVisibleBound = Math.Clamp(Current, 0, ScrollableExtent);
|
||||||
|
float rightVisibleBound = leftVisibleBound + DrawWidth;
|
||||||
|
|
||||||
|
// if a movement is occurring at this time, the bounds below represent the full range of columns that the scroll movement will encompass.
|
||||||
|
// this will be used to ensure that columns do not change state from active to inactive back and forth until they are fully scrolled past.
|
||||||
|
float leftMovementBound = Math.Min(Current, Target);
|
||||||
|
float rightMovementBound = Math.Max(Current, Target) + DrawWidth;
|
||||||
|
|
||||||
|
foreach (var column in Child)
|
||||||
|
{
|
||||||
|
// DrawWidth/DrawPosition do not include shear effects, and we want to know the full extents of the columns post-shear,
|
||||||
|
// so we have to manually compensate.
|
||||||
|
var topLeft = column.ToSpaceOfOtherDrawable(Vector2.Zero, ScrollContent);
|
||||||
|
var bottomRight = column.ToSpaceOfOtherDrawable(new Vector2(column.DrawWidth - column.DrawHeight * SHEAR, 0), ScrollContent);
|
||||||
|
|
||||||
|
bool isCurrentlyVisible = Precision.AlmostBigger(topLeft.X, leftVisibleBound)
|
||||||
|
&& Precision.DefinitelyBigger(rightVisibleBound, bottomRight.X);
|
||||||
|
bool isBeingScrolledToward = Precision.AlmostBigger(topLeft.X, leftMovementBound)
|
||||||
|
&& Precision.DefinitelyBigger(rightMovementBound, bottomRight.X);
|
||||||
|
|
||||||
|
column.Active.Value = isCurrentlyVisible || isBeingScrolledToward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ColumnFlowContainer : FillFlowContainer<ColumnDimContainer>
|
||||||
|
{
|
||||||
|
public IEnumerable<ModColumn> Columns => Children.Select(dimWrapper => dimWrapper.Column);
|
||||||
|
|
||||||
private readonly LayoutValue drawSizeLayout = new LayoutValue(Invalidation.DrawSize);
|
private readonly LayoutValue drawSizeLayout = new LayoutValue(Invalidation.DrawSize);
|
||||||
|
|
||||||
public ModColumnContainer()
|
public ColumnFlowContainer()
|
||||||
{
|
{
|
||||||
AddLayout(drawSizeLayout);
|
AddLayout(drawSizeLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(ModColumn column)
|
public override void Add(ColumnDimContainer dimContainer)
|
||||||
{
|
{
|
||||||
base.Add(column);
|
base.Add(dimContainer);
|
||||||
|
|
||||||
Debug.Assert(column != null);
|
Debug.Assert(dimContainer != null);
|
||||||
column.Shear = Vector2.Zero;
|
dimContainer.Column.Shear = Vector2.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -341,6 +394,63 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ColumnDimContainer : Container
|
||||||
|
{
|
||||||
|
public ModColumn Column { get; }
|
||||||
|
|
||||||
|
public readonly Bindable<bool> Active = new BindableBool();
|
||||||
|
public Action<ColumnDimContainer>? RequestScroll { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
|
public ColumnDimContainer(ModColumn column)
|
||||||
|
{
|
||||||
|
Child = Column = column;
|
||||||
|
column.Active.BindTo(Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Active.BindValueChanged(_ => updateDim(), true);
|
||||||
|
FinishTransforms();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDim()
|
||||||
|
{
|
||||||
|
Colour4 targetColour;
|
||||||
|
|
||||||
|
if (Active.Value)
|
||||||
|
targetColour = Colour4.White;
|
||||||
|
else
|
||||||
|
targetColour = IsHovered ? colours.GrayC : colours.Gray8;
|
||||||
|
|
||||||
|
this.FadeColour(targetColour, 800, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(ClickEvent e)
|
||||||
|
{
|
||||||
|
if (!Active.Value)
|
||||||
|
RequestScroll?.Invoke(this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
base.OnHover(e);
|
||||||
|
updateDim();
|
||||||
|
return Active.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
updateDim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ClickToReturnContainer : Container
|
private class ClickToReturnContainer : Container
|
||||||
{
|
{
|
||||||
public BindableBool HandleMouse { get; } = new BindableBool();
|
public BindableBool HandleMouse { get; } = new BindableBool();
|
||||||
|
@ -14,13 +14,13 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class NestedVerticalScrollContainer : OsuScrollContainer
|
public class NestedVerticalScrollContainer : OsuScrollContainer
|
||||||
{
|
{
|
||||||
private OsuScrollContainer? parentScrollContainer;
|
private ModSelectScreen.ColumnScrollContainer? parentScrollContainer;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
parentScrollContainer = this.FindClosestParent<OsuScrollContainer>();
|
parentScrollContainer = this.FindClosestParent<ModSelectScreen.ColumnScrollContainer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnScroll(ScrollEvent e)
|
protected override bool OnScroll(ScrollEvent e)
|
||||||
|
@ -149,7 +149,7 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddInternal(new HoverClickSounds());
|
AddInternal(new HoverClickSounds(HoverSampleSet.TabSelect));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
private void updateProgress(APIUser user)
|
private void updateProgress(APIUser user)
|
||||||
{
|
{
|
||||||
levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
startDateColumn.Value = dateToString(response.Spotlight.StartDate);
|
startDateColumn.Value = dateToString(response.Spotlight.StartDate);
|
||||||
endDateColumn.Value = dateToString(response.Spotlight.EndDate);
|
endDateColumn.Value = dateToString(response.Spotlight.EndDate);
|
||||||
mapCountColumn.Value = response.BeatmapSets.Count.ToLocalisableString(@"N0");
|
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");
|
private LocalisableString dateToString(DateTimeOffset date) => date.ToLocalisableString(@"yyyy-MM-dd");
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ namespace osu.Game.Overlays.Rankings.Tables
|
|||||||
|
|
||||||
protected override Drawable[] CreateUniqueContent(UserStatistics item) => new Drawable[]
|
protected override Drawable[] CreateUniqueContent(UserStatistics item) => new Drawable[]
|
||||||
{
|
{
|
||||||
new RowText { Text = item.PP?.ToLocalisableString(@"N0"), }
|
new RowText { Text = item.PP?.ToLocalisableString(@"N0") ?? default(LocalisableString), }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,20 @@ namespace osu.Game.Overlays.Settings
|
|||||||
public interface ISettingsItem : IDrawable, IDisposable
|
public interface ISettingsItem : IDrawable, IDisposable
|
||||||
{
|
{
|
||||||
event Action SettingChanged;
|
event Action SettingChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this setting has a classic default (ie. a different default which better aligns with osu-stable expectations).
|
||||||
|
/// </summary>
|
||||||
|
bool HasClassicDefault { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply the classic default value of the associated setting. Will throw if <see cref="HasClassicDefault"/> is <c>false</c>.
|
||||||
|
/// </summary>
|
||||||
|
void ApplyClassicDefault();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply the default value of the associated setting.
|
||||||
|
/// </summary>
|
||||||
|
void ApplyDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
ClassicDefault = false,
|
||||||
LabelText = GameplaySettingsStrings.AlwaysPlayFirstComboBreak,
|
LabelText = GameplaySettingsStrings.AlwaysPlayFirstComboBreak,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.AlwaysPlayFirstComboBreak)
|
Current = config.GetBindable<bool>(OsuSetting.AlwaysPlayFirstComboBreak)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
new SettingsEnumDropdown<ScoringMode>
|
new SettingsEnumDropdown<ScoringMode>
|
||||||
{
|
{
|
||||||
|
ClassicDefault = ScoringMode.Classic,
|
||||||
LabelText = GameplaySettingsStrings.ScoreDisplayMode,
|
LabelText = GameplaySettingsStrings.ScoreDisplayMode,
|
||||||
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
|
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
|
||||||
Keywords = new[] { "scoring" }
|
Keywords = new[] { "scoring" }
|
||||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
ClassicDefault = false,
|
||||||
LabelText = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail,
|
LabelText = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
||||||
Keywords = new[] { "hp", "bar" }
|
Keywords = new[] { "hp", "bar" }
|
||||||
|
@ -37,6 +37,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
},
|
},
|
||||||
new SettingsSlider<double, TimeSlider>
|
new SettingsSlider<double, TimeSlider>
|
||||||
{
|
{
|
||||||
|
ClassicDefault = 0,
|
||||||
LabelText = UserInterfaceStrings.HoldToConfirmActivationTime,
|
LabelText = UserInterfaceStrings.HoldToConfirmActivationTime,
|
||||||
Current = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay),
|
Current = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay),
|
||||||
Keywords = new[] { @"delay" },
|
Keywords = new[] { @"delay" },
|
||||||
|
@ -32,6 +32,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
ClassicDefault = true,
|
||||||
LabelText = UserInterfaceStrings.RightMouseScroll,
|
LabelText = UserInterfaceStrings.RightMouseScroll,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.SongSelectRightMouseScroll),
|
Current = config.GetBindable<bool>(OsuSetting.SongSelectRightMouseScroll),
|
||||||
},
|
},
|
||||||
|
@ -30,6 +30,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public object SettingSourceObject { get; internal set; }
|
public object SettingSourceObject { get; internal set; }
|
||||||
|
|
||||||
|
public const string CLASSIC_DEFAULT_SEARCH_TERM = @"has-classic-default";
|
||||||
|
|
||||||
private IHasCurrentValue<T> controlWithCurrent => Control as IHasCurrentValue<T>;
|
private IHasCurrentValue<T> controlWithCurrent => Control as IHasCurrentValue<T>;
|
||||||
|
|
||||||
protected override Container<Drawable> Content => FlowContent;
|
protected override Container<Drawable> Content => FlowContent;
|
||||||
@ -96,7 +98,21 @@ namespace osu.Game.Overlays.Settings
|
|||||||
set => controlWithCurrent.Current = value;
|
set => controlWithCurrent.Current = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<string> FilterTerms => Keywords == null ? new[] { LabelText.ToString() } : new List<string>(Keywords) { LabelText.ToString() }.ToArray();
|
public virtual IEnumerable<string> FilterTerms
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var keywords = new List<string>(Keywords ?? Array.Empty<string>())
|
||||||
|
{
|
||||||
|
LabelText.ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (HasClassicDefault)
|
||||||
|
keywords.Add(CLASSIC_DEFAULT_SEARCH_TERM);
|
||||||
|
|
||||||
|
return keywords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<string> Keywords { get; set; }
|
public IEnumerable<string> Keywords { get; set; }
|
||||||
|
|
||||||
@ -122,6 +138,32 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
public event Action SettingChanged;
|
public event Action SettingChanged;
|
||||||
|
|
||||||
|
private T classicDefault;
|
||||||
|
|
||||||
|
public bool HasClassicDefault { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A "classic" default value for this setting.
|
||||||
|
/// </summary>
|
||||||
|
public T ClassicDefault
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
classicDefault = value;
|
||||||
|
HasClassicDefault = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyClassicDefault()
|
||||||
|
{
|
||||||
|
if (!HasClassicDefault)
|
||||||
|
throw new InvalidOperationException($"Cannot apply a classic default to a setting which doesn't have one defined via {nameof(ClassicDefault)}.");
|
||||||
|
|
||||||
|
Current.Value = classicDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyDefault() => Current.SetDefault();
|
||||||
|
|
||||||
protected SettingsItem()
|
protected SettingsItem()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -58,7 +59,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
public bool FilteringActive { get; set; }
|
public bool FilteringActive { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved(canBeNull: true)]
|
||||||
private SettingsPanel settingsPanel { get; set; }
|
private SettingsPanel settingsPanel { get; set; }
|
||||||
|
|
||||||
protected SettingsSection()
|
protected SettingsSection()
|
||||||
@ -131,7 +132,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
selectedSection = settingsPanel.CurrentSection.GetBoundCopy();
|
selectedSection = settingsPanel?.CurrentSection.GetBoundCopy() ?? new Bindable<SettingsSection>(this);
|
||||||
selectedSection.BindValueChanged(_ => updateContentFade(), true);
|
selectedSection.BindValueChanged(_ => updateContentFade(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +153,10 @@ namespace osu.Game.Overlays.Settings
|
|||||||
protected override bool OnClick(ClickEvent e)
|
protected override bool OnClick(ClickEvent e)
|
||||||
{
|
{
|
||||||
if (!isCurrentSection)
|
if (!isCurrentSection)
|
||||||
|
{
|
||||||
|
Debug.Assert(settingsPanel != null);
|
||||||
settingsPanel.SectionsContainer.ScrollTo(this);
|
settingsPanel.SectionsContainer.ScrollTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
return base.OnClick(e);
|
return base.OnClick(e);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
protected override IEnumerable<SettingsSection> CreateSections() => new SettingsSection[]
|
protected override IEnumerable<SettingsSection> CreateSections() => new SettingsSection[]
|
||||||
{
|
{
|
||||||
|
// This list should be kept in sync with ScreenBehaviour.
|
||||||
new GeneralSection(),
|
new GeneralSection(),
|
||||||
new SkinSection(),
|
new SkinSection(),
|
||||||
new InputSection(createSubPanel(new KeyBindingPanel())),
|
new InputSection(createSubPanel(new KeyBindingPanel())),
|
||||||
|
@ -109,7 +109,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
logoBounceContainer = new Container
|
logoBounceContainer = new DragContainer
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -402,5 +402,28 @@ namespace osu.Game.Screens.Menu
|
|||||||
impactContainer.ScaleTo(0.96f);
|
impactContainer.ScaleTo(0.96f);
|
||||||
impactContainer.ScaleTo(1.12f, 250);
|
impactContainer.ScaleTo(1.12f, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DragContainer : Container
|
||||||
|
{
|
||||||
|
public override bool DragBlocksClick => false;
|
||||||
|
|
||||||
|
protected override bool OnDragStart(DragStartEvent e) => true;
|
||||||
|
|
||||||
|
protected override void OnDrag(DragEvent e)
|
||||||
|
{
|
||||||
|
Vector2 change = e.MousePosition - e.MouseDownPosition;
|
||||||
|
|
||||||
|
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
|
||||||
|
change *= change.Length <= 0 ? 0 : MathF.Pow(change.Length, 0.6f) / change.Length;
|
||||||
|
|
||||||
|
this.MoveTo(change);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDragEnd(DragEndEvent e)
|
||||||
|
{
|
||||||
|
this.MoveTo(Vector2.Zero, 800, Easing.OutElastic);
|
||||||
|
base.OnDragEnd(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,8 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
|||||||
{
|
{
|
||||||
public override LocalisableString TooltipText =>
|
public override LocalisableString TooltipText =>
|
||||||
Current.Value == 0
|
Current.Value == 0
|
||||||
? new TranslatableString("_", @"{0} ms", base.TooltipText)
|
? LocalisableString.Interpolate($@"{base.TooltipText} ms")
|
||||||
: new TranslatableString("_", @"{0} ms {1}", base.TooltipText, getEarlyLateText(Current.Value));
|
: LocalisableString.Interpolate($@"{base.TooltipText} ms {getEarlyLateText(Current.Value)}");
|
||||||
|
|
||||||
private LocalisableString getEarlyLateText(double value)
|
private LocalisableString getEarlyLateText(double value)
|
||||||
{
|
{
|
||||||
|
@ -2,27 +2,36 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.MathUtils
|
namespace osu.Game.Utils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A PRNG specified in http://heliosphan.org/fastrandom.html.
|
/// A PRNG specified in http://heliosphan.org/fastrandom.html.
|
||||||
|
/// Should only be used to match legacy behaviour. See <see cref="RNG"/> for a newer alternative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FastRandom
|
/// <remarks>
|
||||||
|
/// Known in osu-stable code as `FastRandom`.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyRandom
|
||||||
{
|
{
|
||||||
private const double int_to_real = 1.0 / (int.MaxValue + 1.0);
|
private const double int_to_real = 1.0 / (int.MaxValue + 1.0);
|
||||||
private const uint int_mask = 0x7FFFFFFF;
|
private const uint int_mask = 0x7FFFFFFF;
|
||||||
private const uint y_initial = 842502087;
|
private const uint y = 842502087;
|
||||||
private const uint z_initial = 3579807591;
|
private const uint z = 3579807591;
|
||||||
private const uint w_initial = 273326509;
|
private const uint w = 273326509;
|
||||||
private uint x, y = y_initial, z = z_initial, w = w_initial;
|
|
||||||
|
|
||||||
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)
|
: this(Environment.TickCount)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -33,11 +42,11 @@ namespace osu.Game.Rulesets.Catch.MathUtils
|
|||||||
/// <returns>The random value.</returns>
|
/// <returns>The random value.</returns>
|
||||||
public uint NextUInt()
|
public uint NextUInt()
|
||||||
{
|
{
|
||||||
uint t = x ^ (x << 11);
|
uint t = X ^ (X << 11);
|
||||||
x = y;
|
X = Y;
|
||||||
y = z;
|
Y = Z;
|
||||||
z = w;
|
Z = W;
|
||||||
return w = w ^ (w >> 19) ^ t ^ (t >> 8);
|
return W = W ^ (W >> 19) ^ t ^ (t >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
@ -35,7 +35,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="10.10.0" />
|
<PackageReference Include="Realm" Version="10.10.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.423.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.428.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.14.1" />
|
<PackageReference Include="Sentry" Version="3.14.1" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.30.1" />
|
<PackageReference Include="SharpCompress" Version="0.30.1" />
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.423.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.428.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.422.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
||||||
@ -84,7 +84,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.423.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.428.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.30.1" />
|
<PackageReference Include="SharpCompress" Version="0.30.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
|
Reference in New Issue
Block a user