Compare commits
1 Commits
2025.830.0
...
e78c8fa03d
| Author | SHA1 | Date | |
|---|---|---|---|
| e78c8fa03d |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -148,7 +148,9 @@ jobs:
|
|||||||
# https://github.com/dotnet/macios/issues/19157
|
# https://github.com/dotnet/macios/issues/19157
|
||||||
# https://github.com/actions/runner-images/issues/12758
|
# https://github.com/actions/runner-images/issues/12758
|
||||||
- name: Use Xcode 16.4
|
- name: Use Xcode 16.4
|
||||||
run: sudo xcode-select -switch /Applications/Xcode_16.4.app
|
run: |
|
||||||
|
sudo xcode-select -switch /Applications/Xcode_16.4.app
|
||||||
|
xcodebuild -downloadPlatform iOS
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build -c Debug osu.iOS.slnf
|
run: dotnet build -c Debug osu.iOS.slnf
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"dotnet.defaultSolution": "osu.Desktop.slnf"
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
|
|
||||||
public override BindableBool ComboBasedSize { get; } = new BindableBool(true);
|
public override BindableBool ComboBasedSize { get; } = new BindableBool(true);
|
||||||
|
|
||||||
public override float DefaultFlashlightSize => 203.125f;
|
public override float DefaultFlashlightSize => 325;
|
||||||
|
|
||||||
protected override Flashlight CreateFlashlight() => new CatchFlashlight(this, playfield);
|
protected override Flashlight CreateFlashlight() => new CatchFlashlight(this, playfield);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@@ -17,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
public override string Acronym => "FF";
|
public override string Acronym => "FF";
|
||||||
public override LocalisableString Description => "The fruits are... floating?";
|
public override LocalisableString Description => "The fruits are... floating?";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override IconUsage? Icon => OsuIcon.ModFloatingFruits;
|
public override IconUsage? Icon => FontAwesome.Solid.Cloud;
|
||||||
|
|
||||||
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset)
|
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
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.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
public override LocalisableString Description => "Dashing by default, slow down!";
|
public override LocalisableString Description => "Dashing by default, slow down!";
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override IconUsage? Icon => OsuIcon.ModMovingFast;
|
public override IconUsage? Icon => FontAwesome.Solid.Running;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax) };
|
||||||
|
|
||||||
private DrawableCatchRuleset drawableRuleset = null!;
|
private DrawableCatchRuleset drawableRuleset = null!;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => "No more tricky speed changes!";
|
public override LocalisableString Description => "No more tricky speed changes!";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModConstantSpeed;
|
public override IconUsage? Icon => FontAwesome.Solid.Equals;
|
||||||
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
@@ -16,7 +14,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Cover";
|
public override string Name => "Cover";
|
||||||
public override string Acronym => "CO";
|
public override string Acronym => "CO";
|
||||||
public override IconUsage? Icon => OsuIcon.ModCover;
|
|
||||||
|
|
||||||
public override LocalisableString Description => @"Decrease the playfield's viewing area.";
|
public override LocalisableString Description => @"Decrease the playfield's viewing area.";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
@@ -15,7 +13,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Name => "Dual Stages";
|
public override string Name => "Dual Stages";
|
||||||
public override string Acronym => "DS";
|
public override string Acronym => "DS";
|
||||||
public override LocalisableString Description => @"Double the stages, double the fun!";
|
public override LocalisableString Description => @"Double the stages, double the fun!";
|
||||||
public override IconUsage? Icon => OsuIcon.ModDualStages;
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
@@ -14,7 +12,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Fade In";
|
public override string Name => "Fade In";
|
||||||
public override string Acronym => "FI";
|
public override string Acronym => "FI";
|
||||||
public override IconUsage? Icon => OsuIcon.ModFadeIn;
|
|
||||||
public override LocalisableString Description => @"Keys appear out of nowhere!";
|
public override LocalisableString Description => @"Keys appear out of nowhere!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool ValidForFreestyleAsRequiredMod => false;
|
public override bool ValidForFreestyleAsRequiredMod => false;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
@@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => @"Replaces all hold notes with normal notes.";
|
public override LocalisableString Description => @"Replaces all hold notes with normal notes.";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModHoldOff;
|
public override IconUsage? Icon => FontAwesome.Solid.DotCircle;
|
||||||
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => "Hold the keys. To the beat.";
|
public override LocalisableString Description => "Hold the keys. To the beat.";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModInvert;
|
public override IconUsage? Icon => FontAwesome.Solid.YinYang;
|
||||||
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 1;
|
public override int KeyCount => 1;
|
||||||
public override string Name => "One Key";
|
public override string Name => "One Key";
|
||||||
public override string Acronym => "1K";
|
public override string Acronym => "1K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModOneKey;
|
|
||||||
public override LocalisableString Description => @"Play with one key.";
|
public override LocalisableString Description => @"Play with one key.";
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 10;
|
public override int KeyCount => 10;
|
||||||
public override string Name => "Ten Keys";
|
public override string Name => "Ten Keys";
|
||||||
public override string Acronym => "10K";
|
public override string Acronym => "10K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTenKeys;
|
|
||||||
public override LocalisableString Description => @"Play with ten keys.";
|
public override LocalisableString Description => @"Play with ten keys.";
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 2;
|
public override int KeyCount => 2;
|
||||||
public override string Name => "Two Keys";
|
public override string Name => "Two Keys";
|
||||||
public override string Acronym => "2K";
|
public override string Acronym => "2K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
|
|
||||||
public override LocalisableString Description => @"Play with two keys.";
|
public override LocalisableString Description => @"Play with two keys.";
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 3;
|
public override int KeyCount => 3;
|
||||||
public override string Name => "Three Keys";
|
public override string Name => "Three Keys";
|
||||||
public override string Acronym => "3K";
|
public override string Acronym => "3K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
|
|
||||||
public override LocalisableString Description => @"Play with three keys.";
|
public override LocalisableString Description => @"Play with three keys.";
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 4;
|
public override int KeyCount => 4;
|
||||||
public override string Name => "Four Keys";
|
public override string Name => "Four Keys";
|
||||||
public override string Acronym => "4K";
|
public override string Acronym => "4K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModFourKeys;
|
|
||||||
public override LocalisableString Description => @"Play with four keys.";
|
public override LocalisableString Description => @"Play with four keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 5;
|
public override int KeyCount => 5;
|
||||||
public override string Name => "Five Keys";
|
public override string Name => "Five Keys";
|
||||||
public override string Acronym => "5K";
|
public override string Acronym => "5K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModFiveKeys;
|
|
||||||
public override LocalisableString Description => @"Play with five keys.";
|
public override LocalisableString Description => @"Play with five keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 6;
|
public override int KeyCount => 6;
|
||||||
public override string Name => "Six Keys";
|
public override string Name => "Six Keys";
|
||||||
public override string Acronym => "6K";
|
public override string Acronym => "6K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSixKeys;
|
|
||||||
public override LocalisableString Description => @"Play with six keys.";
|
public override LocalisableString Description => @"Play with six keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 7;
|
public override int KeyCount => 7;
|
||||||
public override string Name => "Seven Keys";
|
public override string Name => "Seven Keys";
|
||||||
public override string Acronym => "7K";
|
public override string Acronym => "7K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSevenKeys;
|
|
||||||
public override LocalisableString Description => @"Play with seven keys.";
|
public override LocalisableString Description => @"Play with seven keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 8;
|
public override int KeyCount => 8;
|
||||||
public override string Name => "Eight Keys";
|
public override string Name => "Eight Keys";
|
||||||
public override string Acronym => "8K";
|
public override string Acronym => "8K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModEightKeys;
|
|
||||||
public override LocalisableString Description => @"Play with eight keys.";
|
public override LocalisableString Description => @"Play with eight keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override int KeyCount => 9;
|
public override int KeyCount => 9;
|
||||||
public override string Name => "Nine Keys";
|
public override string Name => "Nine Keys";
|
||||||
public override string Acronym => "9K";
|
public override string Acronym => "9K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModNineKeys;
|
|
||||||
public override LocalisableString Description => @"Play with nine keys.";
|
public override LocalisableString Description => @"Play with nine keys.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
@@ -28,8 +26,6 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
|
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 0.9;
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModNoRelease;
|
|
||||||
|
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ManiaModHoldOff) };
|
public override Type[] IncompatibleMods => new[] { typeof(ManiaModHoldOff) };
|
||||||
|
|||||||
@@ -32,6 +32,26 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestComboBasedSize([Values] bool comboBasedSize) => CreateModTest(new ModTestData { Mod = new OsuModFlashlight { ComboBasedSize = { Value = comboBasedSize } }, PassCondition = () => true });
|
public void TestComboBasedSize([Values] bool comboBasedSize) => CreateModTest(new ModTestData { Mod = new OsuModFlashlight { ComboBasedSize = { Value = comboBasedSize } }, PassCondition = () => true });
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPlayfieldBasedSize()
|
||||||
|
{
|
||||||
|
OsuModFlashlight flashlight;
|
||||||
|
CreateModTest(new ModTestData
|
||||||
|
{
|
||||||
|
Mods = [flashlight = new OsuModFlashlight(), new OsuModBarrelRoll()],
|
||||||
|
PassCondition = () =>
|
||||||
|
{
|
||||||
|
var flashlightOverlay = Player.DrawableRuleset.Overlays
|
||||||
|
.ChildrenOfType<ModFlashlight<OsuHitObject>.Flashlight>()
|
||||||
|
.First();
|
||||||
|
|
||||||
|
// the combo check is here because the flashlight radius decreases for the first time at 100 combo
|
||||||
|
// and hardcoding it here eliminates the need to meddle in flashlight internals further by e.g. exposing `GetComboScaleFor()`
|
||||||
|
return flashlightOverlay.GetSize() < flashlight.DefaultFlashlightSize && Player.GameplayState.ScoreProcessor.Combo.Value < 100;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSliderDimsOnlyAfterStartTime()
|
public void TestSliderDimsOnlyAfterStartTime()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ namespace osu.Game.Rulesets.Osu.HUD
|
|||||||
if (PositionDisplayStyle.Value == PositionDisplay.Normalised && lastObjectPosition != null)
|
if (PositionDisplayStyle.Value == PositionDisplay.Normalised && lastObjectPosition != null)
|
||||||
{
|
{
|
||||||
hitPosition = AccuracyHeatmap.FindRelativeHitPosition(lastObjectPosition.Value, ((OsuHitObject)circleJudgement.HitObject).StackedEndPosition,
|
hitPosition = AccuracyHeatmap.FindRelativeHitPosition(lastObjectPosition.Value, ((OsuHitObject)circleJudgement.HitObject).StackedEndPosition,
|
||||||
circleJudgement.CursorPositionAtHit.Value, objectRadius, 45) * (inner_portion / 2);
|
circleJudgement.CursorPositionAtHit.Value, objectRadius, 45) * 0.5f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Name => @"Alternate";
|
public override string Name => @"Alternate";
|
||||||
public override string Acronym => @"AL";
|
public override string Acronym => @"AL";
|
||||||
public override LocalisableString Description => @"Don't use the same key twice in a row!";
|
public override LocalisableString Description => @"Don't use the same key twice in a row!";
|
||||||
public override IconUsage? Icon => OsuIcon.ModAlternate;
|
public override IconUsage? Icon => FontAwesome.Solid.Keyboard;
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModSingleTap) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModSingleTap) }).ToArray();
|
||||||
|
|
||||||
protected override bool CheckValidNewAction(OsuAction action) => LastAcceptedAction != action;
|
protected override bool CheckValidNewAction(OsuAction action) => LastAcceptedAction != action;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
@@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Acronym => "AD";
|
public override string Acronym => "AD";
|
||||||
public override LocalisableString Description => "Never trust the approach circles...";
|
public override LocalisableString Description => "Never trust the approach circles...";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override IconUsage? Icon => OsuIcon.ModApproachDifferent;
|
public override IconUsage? Icon { get; } = FontAwesome.Regular.Circle;
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles), typeof(OsuModFreezeFrame) };
|
public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles), typeof(OsuModFreezeFrame) };
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using osu.Framework.Graphics.Textures;
|
|||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override LocalisableString Description => "Play with blinds on your screen.";
|
public override LocalisableString Description => "Play with blinds on your screen.";
|
||||||
public override string Acronym => "BL";
|
public override string Acronym => "BL";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModBlinds;
|
public override IconUsage? Icon => FontAwesome.Solid.Adjust;
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
|
|
||||||
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1;
|
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1;
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@@ -23,7 +21,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Bloom";
|
public override string Name => "Bloom";
|
||||||
public override string Acronym => "BM";
|
public override string Acronym => "BM";
|
||||||
public override IconUsage? Icon => OsuIcon.ModBloom;
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "The cursor blooms into.. a larger cursor!";
|
public override LocalisableString Description => "The cursor blooms into.. a larger cursor!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -36,8 +34,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModBubbles;
|
|
||||||
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
|
|
||||||
// Compatibility with these seems potentially feasible in the future, blocked for now because they don't work as one would expect
|
// Compatibility with these seems potentially feasible in the future, blocked for now because they don't work as one would expect
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override string Acronym => "DF";
|
public override string Acronym => "DF";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModDeflate;
|
public override IconUsage? Icon => FontAwesome.Solid.CompressArrowsAlt;
|
||||||
|
|
||||||
public override LocalisableString Description => "Hit them at the right size!";
|
public override LocalisableString Description => "Hit them at the right size!";
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Depth";
|
public override string Name => "Depth";
|
||||||
public override string Acronym => "DP";
|
public override string Acronym => "DP";
|
||||||
public override IconUsage? Icon => OsuIcon.ModDepth;
|
public override IconUsage? Icon => FontAwesome.Solid.Cube;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "3D. Almost.";
|
public override LocalisableString Description => "3D. Almost.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override BindableBool ComboBasedSize { get; } = new BindableBool(true);
|
public override BindableBool ComboBasedSize { get; } = new BindableBool(true);
|
||||||
|
|
||||||
public override float DefaultFlashlightSize => 125;
|
public override float DefaultFlashlightSize => 200;
|
||||||
|
|
||||||
private OsuFlashlight flashlight = null!;
|
private OsuFlashlight flashlight = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -21,8 +19,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override string Acronym => "FR";
|
public override string Acronym => "FR";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModFreezeFrame;
|
|
||||||
|
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public override LocalisableString Description => "Burn the notes into your memory.";
|
public override LocalisableString Description => "Burn the notes into your memory.";
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
@@ -14,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override string Acronym => "GR";
|
public override string Acronym => "GR";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModGrow;
|
public override IconUsage? Icon => FontAwesome.Solid.ArrowsAltV;
|
||||||
|
|
||||||
public override LocalisableString Description => "Hit them at the right size!";
|
public override LocalisableString Description => "Hit them at the right size!";
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using osu.Framework.Localisation;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Magnetised";
|
public override string Name => "Magnetised";
|
||||||
public override string Acronym => "MG";
|
public override string Acronym => "MG";
|
||||||
public override IconUsage? Icon => OsuIcon.ModMagnetised;
|
public override IconUsage? Icon => FontAwesome.Solid.Magnet;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "No need to chase the circles – your cursor is a magnet!";
|
public override LocalisableString Description => "No need to chase the circles – your cursor is a magnet!";
|
||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
|||||||
@@ -4,12 +4,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -25,7 +23,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Repel";
|
public override string Name => "Repel";
|
||||||
public override string Acronym => "RP";
|
public override string Acronym => "RP";
|
||||||
public override IconUsage? Icon => OsuIcon.ModRepel;
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "Hit objects run away!";
|
public override LocalisableString Description => "Hit objects run away!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
@@ -13,7 +11,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => @"Single Tap";
|
public override string Name => @"Single Tap";
|
||||||
public override string Acronym => @"SG";
|
public override string Acronym => @"SG";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSingleTap;
|
|
||||||
public override LocalisableString Description => @"You must only use one key!";
|
public override LocalisableString Description => @"You must only use one key!";
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAlternate) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAlternate) }).ToArray();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -18,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Spin In";
|
public override string Name => "Spin In";
|
||||||
public override string Acronym => "SI";
|
public override string Acronym => "SI";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSpinIn;
|
public override IconUsage? Icon => FontAwesome.Solid.Undo;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "Circles spin in. No approach circles.";
|
public override LocalisableString Description => "Circles spin in. No approach circles.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@@ -26,7 +24,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => @"Strict Tracking";
|
public override string Name => @"Strict Tracking";
|
||||||
public override string Acronym => @"ST";
|
public override string Acronym => @"ST";
|
||||||
public override IconUsage? Icon => OsuIcon.ModStrictTracking;
|
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => @"Once you start a slider, follow precisely or get a miss.";
|
public override LocalisableString Description => @"Once you start a slider, follow precisely or get a miss.";
|
||||||
public override double ScoreMultiplier => 1.0;
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Name => "Target Practice";
|
public override string Name => "Target Practice";
|
||||||
public override string Acronym => "TP";
|
public override string Acronym => "TP";
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override IconUsage? Icon => OsuIcon.ModTargetPractice;
|
public override IconUsage? Icon => OsuIcon.ModTarget;
|
||||||
public override LocalisableString Description => @"Practice keeping up with the beat of the song.";
|
public override LocalisableString Description => @"Practice keeping up with the beat of the song.";
|
||||||
public override double ScoreMultiplier => 0.1;
|
public override double ScoreMultiplier => 0.1;
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@@ -20,7 +18,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Traceable";
|
public override string Name => "Traceable";
|
||||||
public override string Acronym => "TC";
|
public override string Acronym => "TC";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTraceable;
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "Put your faith in the approach circles...";
|
public override LocalisableString Description => "Put your faith in the approach circles...";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Transform";
|
public override string Name => "Transform";
|
||||||
public override string Acronym => "TR";
|
public override string Acronym => "TR";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTransform;
|
public override IconUsage? Icon => FontAwesome.Solid.ArrowsAlt;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "Everything rotates. EVERYTHING.";
|
public override LocalisableString Description => "Everything rotates. EVERYTHING.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Wiggle";
|
public override string Name => "Wiggle";
|
||||||
public override string Acronym => "WG";
|
public override string Acronym => "WG";
|
||||||
public override IconUsage? Icon => OsuIcon.ModWiggle;
|
public override IconUsage? Icon => FontAwesome.Solid.Certificate;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override LocalisableString Description => "They just won't stay still...";
|
public override LocalisableString Description => "They just won't stay still...";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -3,10 +3,7 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Taiko.Mods;
|
using osu.Game.Rulesets.Taiko.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@@ -15,34 +12,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
|
|||||||
{
|
{
|
||||||
public partial class TestSceneTaikoModFlashlight : TaikoModTestScene
|
public partial class TestSceneTaikoModFlashlight : TaikoModTestScene
|
||||||
{
|
{
|
||||||
[Test]
|
|
||||||
public void TestAspectRatios([Values] bool withClassicMod)
|
|
||||||
{
|
|
||||||
if (withClassicMod)
|
|
||||||
CreateModTest(new ModTestData { Mods = new Mod[] { new TaikoModFlashlight(), new TaikoModClassic() }, PassCondition = () => true });
|
|
||||||
else
|
|
||||||
CreateModTest(new ModTestData { Mod = new TaikoModFlashlight(), PassCondition = () => true });
|
|
||||||
|
|
||||||
AddStep("clear dim", () => LocalConfig.SetValue(OsuSetting.DimLevel, 0.0));
|
|
||||||
|
|
||||||
AddStep("reset", () => Stack.FillMode = FillMode.Stretch);
|
|
||||||
AddStep("set to 16:9", () =>
|
|
||||||
{
|
|
||||||
Stack.FillAspectRatio = 16 / 9f;
|
|
||||||
Stack.FillMode = FillMode.Fit;
|
|
||||||
});
|
|
||||||
AddStep("set to 4:3", () =>
|
|
||||||
{
|
|
||||||
Stack.FillAspectRatio = 4 / 3f;
|
|
||||||
Stack.FillMode = FillMode.Fit;
|
|
||||||
});
|
|
||||||
AddSliderStep("aspect ratio", 0.01f, 5f, 1f, v =>
|
|
||||||
{
|
|
||||||
Stack.FillAspectRatio = v;
|
|
||||||
Stack.FillMode = FillMode.Fit;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(1f)]
|
[TestCase(1f)]
|
||||||
[TestCase(0.5f)]
|
[TestCase(0.5f)]
|
||||||
[TestCase(1.25f)]
|
[TestCase(1.25f)]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@@ -18,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
public override string Acronym => "CS";
|
public override string Acronym => "CS";
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 0.9;
|
||||||
public override LocalisableString Description => "No more tricky speed changes!";
|
public override LocalisableString Description => "No more tricky speed changes!";
|
||||||
public override IconUsage? Icon => OsuIcon.ModConstantSpeed;
|
public override IconUsage? Icon => FontAwesome.Solid.Equals;
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
|
|
||||||
public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset)
|
public void ApplyToDrawableRuleset(DrawableRuleset<TaikoHitObject> drawableRuleset)
|
||||||
|
|||||||
@@ -47,15 +47,28 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
{
|
{
|
||||||
this.taikoPlayfield = taikoPlayfield;
|
this.taikoPlayfield = taikoPlayfield;
|
||||||
|
|
||||||
FlashlightSize = new Vector2(0, GetSize());
|
FlashlightSize = adjustSizeForPlayfieldAspectRatio(GetSize());
|
||||||
FlashlightSmoothness = 1.4f;
|
FlashlightSmoothness = 1.4f;
|
||||||
|
|
||||||
AddLayout(flashlightProperties);
|
AddLayout(flashlightProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the aspect ratio-adjusted size of the flashlight.
|
||||||
|
/// This ensures that the size of the flashlight remains independent of taiko-specific aspect ratio adjustments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">
|
||||||
|
/// The size of the flashlight.
|
||||||
|
/// The value provided here should always come from <see cref="ModFlashlight{T}.Flashlight.GetSize"/>.
|
||||||
|
/// </param>
|
||||||
|
private Vector2 adjustSizeForPlayfieldAspectRatio(float size)
|
||||||
|
{
|
||||||
|
return new Vector2(0, size * taikoPlayfield.Parent!.Scale.Y);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateFlashlightSize(float size)
|
protected override void UpdateFlashlightSize(float size)
|
||||||
{
|
{
|
||||||
this.TransformTo(nameof(FlashlightSize), new Vector2(0, size), FLASHLIGHT_FADE_DURATION);
|
this.TransformTo(nameof(FlashlightSize), adjustSizeForPlayfieldAspectRatio(size), FLASHLIGHT_FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string FragmentShader => "CircularFlashlight";
|
protected override string FragmentShader => "CircularFlashlight";
|
||||||
@@ -69,7 +82,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre);
|
FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre);
|
||||||
|
|
||||||
ClearTransforms(targetMember: nameof(FlashlightSize));
|
ClearTransforms(targetMember: nameof(FlashlightSize));
|
||||||
FlashlightSize = new Vector2(0, GetSize());
|
FlashlightSize = adjustSizeForPlayfieldAspectRatio(GetSize());
|
||||||
|
|
||||||
flashlightProperties.Validate();
|
flashlightProperties.Validate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@@ -23,7 +21,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
public override string Acronym => "SR";
|
public override string Acronym => "SR";
|
||||||
public override double ScoreMultiplier => 0.6;
|
public override double ScoreMultiplier => 0.6;
|
||||||
public override LocalisableString Description => "Simplify tricky rhythms!";
|
public override LocalisableString Description => "Simplify tricky rhythms!";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSimplifiedRhythm;
|
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
|
|
||||||
[SettingSource("1/3 to 1/2 conversion", "Converts 1/3 patterns to 1/2 rhythm.")]
|
[SettingSource("1/3 to 1/2 conversion", "Converts 1/3 patterns to 1/2 rhythm.")]
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@@ -26,7 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => @"Single Tap";
|
public override string Name => @"Single Tap";
|
||||||
public override string Acronym => @"SG";
|
public override string Acronym => @"SG";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSingleTap;
|
|
||||||
public override LocalisableString Description => @"One key for dons, one key for kats.";
|
public override LocalisableString Description => @"One key for dons, one key for kats.";
|
||||||
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@@ -18,7 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
public override string Name => "Swap";
|
public override string Name => "Swap";
|
||||||
public override string Acronym => "SW";
|
public override string Acronym => "SW";
|
||||||
public override LocalisableString Description => @"Dons become kats, kats become dons";
|
public override LocalisableString Description => @"Dons become kats, kats become dons";
|
||||||
public override IconUsage? Icon => OsuIcon.ModSwap;
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModRandom)).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModRandom)).ToArray();
|
||||||
|
|||||||
@@ -66,18 +66,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddStep("toggle black background", () => blackBackground?.FadeTo(1 - blackBackground.Alpha, 300, Easing.OutQuint));
|
AddStep("toggle black background", () => blackBackground?.FadeTo(1 - blackBackground.Alpha, 300, Easing.OutQuint));
|
||||||
|
|
||||||
AddSliderStep("leaderboard width", 0, 800, 300, v =>
|
|
||||||
{
|
|
||||||
if (leaderboard.IsNotNull())
|
|
||||||
leaderboard.Width = v;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSliderStep("leaderboard height", 0, 1000, 300, v =>
|
|
||||||
{
|
|
||||||
if (leaderboard.IsNotNull())
|
|
||||||
leaderboard.Height = v;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddSliderStep("set player score", 50, 1_000_000, 700_000, v => gameplayState.ScoreProcessor.TotalScore.Value = v);
|
AddSliderStep("set player score", 50, 1_000_000, 700_000, v => gameplayState.ScoreProcessor.TotalScore.Value = v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,45 +108,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddUntilStep("wait for 1st spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(1));
|
AddUntilStep("wait for 1st spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestLongScores()
|
|
||||||
{
|
|
||||||
AddStep("set scores", () =>
|
|
||||||
{
|
|
||||||
var friend = new APIUser { Username = "Friend", Id = 1337 };
|
|
||||||
|
|
||||||
var api = (DummyAPIAccess)API;
|
|
||||||
|
|
||||||
api.Friends.Clear();
|
|
||||||
api.Friends.Add(new APIRelation
|
|
||||||
{
|
|
||||||
Mutual = true,
|
|
||||||
RelationType = RelationType.Friend,
|
|
||||||
TargetID = friend.OnlineID,
|
|
||||||
TargetUser = friend
|
|
||||||
});
|
|
||||||
|
|
||||||
// this is dodgy but anything less dodgy is a lot of work
|
|
||||||
((Bindable<LeaderboardScores?>)leaderboardManager.Scores).Value = LeaderboardScores.Success(new[]
|
|
||||||
{
|
|
||||||
new ScoreInfo { User = new APIUser { Username = "Top", Id = 2 }, TotalScore = 900_000_000, Accuracy = 0.99, MaxCombo = 999999 },
|
|
||||||
new ScoreInfo { User = new APIUser { Username = "Second", Id = 14 }, TotalScore = 800_000_000, Accuracy = 0.9, MaxCombo = 888888 },
|
|
||||||
new ScoreInfo { User = friend, TotalScore = 700_000_000, Accuracy = 0.88, MaxCombo = 777777 },
|
|
||||||
}, 3, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
createLeaderboard();
|
|
||||||
|
|
||||||
AddStep("set score to 650k", () => gameplayState.ScoreProcessor.TotalScore.Value = 650_000_000);
|
|
||||||
AddUntilStep("wait for 4th spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(4));
|
|
||||||
AddStep("set score to 750k", () => gameplayState.ScoreProcessor.TotalScore.Value = 750_000_000);
|
|
||||||
AddUntilStep("wait for 3rd spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(3));
|
|
||||||
AddStep("set score to 850k", () => gameplayState.ScoreProcessor.TotalScore.Value = 850_000_000);
|
|
||||||
AddUntilStep("wait for 2nd spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(2));
|
|
||||||
AddStep("set score to 950k", () => gameplayState.ScoreProcessor.TotalScore.Value = 950_000_000);
|
|
||||||
AddUntilStep("wait for 1st spot", () => leaderboard.TrackedScore!.ScorePosition.Value, () => Is.EqualTo(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLayoutWithManyScores()
|
public void TestLayoutWithManyScores()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,14 +24,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
protected TestReplayPlayer Player = null!;
|
protected TestReplayPlayer Player = null!;
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestFailedBeatmapLoad()
|
|
||||||
{
|
|
||||||
loadPlayerWithBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo, withHitObjects: false));
|
|
||||||
|
|
||||||
AddUntilStep("wait for exit", () => Player.IsCurrentScreen());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPauseViaSpace()
|
public void TestPauseViaSpace()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@@ -43,8 +42,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
private DialogOverlay dialogOverlay = null!;
|
private DialogOverlay dialogOverlay = null!;
|
||||||
|
|
||||||
private LeaderboardManager leaderboardManager = null!;
|
private LeaderboardManager leaderboardManager = null!;
|
||||||
|
private RealmPopulatingOnlineLookupSource lookupSource = null!;
|
||||||
private readonly IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
@@ -54,7 +52,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
||||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, API));
|
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, API));
|
||||||
dependencies.Cache(leaderboardManager = new LeaderboardManager());
|
dependencies.Cache(leaderboardManager = new LeaderboardManager());
|
||||||
dependencies.CacheAs(onlineLookupResult);
|
dependencies.Cache(lookupSource = new RealmPopulatingOnlineLookupSource());
|
||||||
|
|
||||||
Dependencies.Cache(Realm);
|
Dependencies.Cache(Realm);
|
||||||
|
|
||||||
@@ -70,6 +68,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
});
|
});
|
||||||
|
|
||||||
LoadComponent(leaderboardManager);
|
LoadComponent(leaderboardManager);
|
||||||
|
LoadComponent(lookupSource);
|
||||||
|
|
||||||
Child = contentContainer = new OsuContextMenuContainer
|
Child = contentContainer = new OsuContextMenuContainer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,12 +4,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Extensions;
|
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Screens.SelectV2;
|
using osu.Game.Screens.SelectV2;
|
||||||
|
|
||||||
@@ -17,25 +18,64 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
public partial class TestSceneBeatmapMetadataWedge : SongSelectComponentsTestScene
|
public partial class TestSceneBeatmapMetadataWedge : SongSelectComponentsTestScene
|
||||||
{
|
{
|
||||||
private BeatmapMetadataWedge wedge = null!;
|
private APIBeatmapSet? currentOnlineSet;
|
||||||
|
|
||||||
[Cached(typeof(IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>))]
|
private BeatmapMetadataWedge wedge = null!;
|
||||||
private Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Child = wedge = new BeatmapMetadataWedge
|
var lookupSource = new RealmPopulatingOnlineLookupSource();
|
||||||
|
Child = new DependencyProvidingContainer
|
||||||
{
|
{
|
||||||
State = { Value = Visibility.Visible },
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
CachedDependencies = [(typeof(RealmPopulatingOnlineLookupSource), lookupSource)],
|
||||||
|
Children =
|
||||||
|
[
|
||||||
|
lookupSource,
|
||||||
|
wedge = new BeatmapMetadataWedge
|
||||||
|
{
|
||||||
|
State = { Value = Visibility.Visible },
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("register request handling", () =>
|
||||||
|
{
|
||||||
|
((DummyAPIAccess)API).HandleRequest = request =>
|
||||||
|
{
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case GetBeatmapSetRequest set:
|
||||||
|
if (set.ID == currentOnlineSet?.OnlineID)
|
||||||
|
{
|
||||||
|
set.TriggerSuccess(currentOnlineSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestShowHide()
|
public void TestShowHide()
|
||||||
{
|
{
|
||||||
AddStep("all metrics", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("all metrics", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("hide wedge", () => wedge.Hide());
|
AddStep("hide wedge", () => wedge.Hide());
|
||||||
AddStep("show wedge", () => wedge.Show());
|
AddStep("show wedge", () => wedge.Show());
|
||||||
@@ -44,63 +84,67 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestVariousMetrics()
|
public void TestVariousMetrics()
|
||||||
{
|
{
|
||||||
AddStep("all metrics", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("all metrics", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
AddStep("null beatmap", () => Beatmap.SetDefault());
|
AddStep("null beatmap", () => Beatmap.SetDefault());
|
||||||
AddStep("no source", () =>
|
AddStep("no source", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
working.Metadata.Source = string.Empty;
|
working.Metadata.Source = string.Empty;
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddStep("no success rate", () =>
|
AddStep("no success rate", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Beatmaps.Single().PlayCount = 0;
|
onlineSet.Beatmaps.Single().PlayCount = 0;
|
||||||
online.Result!.Beatmaps.Single().PassCount = 0;
|
onlineSet.Beatmaps.Single().PassCount = 0;
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddStep("no user ratings", () =>
|
AddStep("no user ratings", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Ratings = Array.Empty<int>();
|
onlineSet.Ratings = Array.Empty<int>();
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddStep("no fail times", () =>
|
AddStep("no fail times", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Beatmaps.Single().FailTimes = null;
|
onlineSet.Beatmaps.Single().FailTimes = null;
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddStep("no metrics", () =>
|
AddStep("no metrics", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Ratings = Array.Empty<int>();
|
onlineSet.Ratings = Array.Empty<int>();
|
||||||
online.Result!.Beatmaps.Single().FailTimes = null;
|
onlineSet.Beatmaps.Single().FailTimes = null;
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddStep("local beatmap", () =>
|
AddStep("local beatmap", () =>
|
||||||
{
|
{
|
||||||
var (working, _) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
working.BeatmapInfo.OnlineID = 0;
|
working.BeatmapInfo.OnlineID = 0;
|
||||||
|
|
||||||
onlineLookupResult.Value = null;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -110,16 +154,16 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
AddStep("long text", () =>
|
AddStep("long text", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
working.BeatmapInfo.Metadata.Author = new RealmUser { Username = "Verrrrryyyy llooonngggggg author" };
|
working.BeatmapInfo.Metadata.Author = new RealmUser { Username = "Verrrrryyyy llooonngggggg author" };
|
||||||
working.BeatmapInfo.Metadata.Source = "Verrrrryyyy llooonngggggg source";
|
working.BeatmapInfo.Metadata.Source = "Verrrrryyyy llooonngggggg source";
|
||||||
working.BeatmapInfo.Metadata.Tags = string.Join(' ', Enumerable.Repeat(working.BeatmapInfo.Metadata.Tags, 3));
|
working.BeatmapInfo.Metadata.Tags = string.Join(' ', Enumerable.Repeat(working.BeatmapInfo.Metadata.Tags, 3));
|
||||||
online.Result!.Genre = new BeatmapSetOnlineGenre { Id = 12, Name = "Verrrrryyyy llooonngggggg genre" };
|
onlineSet.Genre = new BeatmapSetOnlineGenre { Id = 12, Name = "Verrrrryyyy llooonngggggg genre" };
|
||||||
online.Result!.Language = new BeatmapSetOnlineLanguage { Id = 12, Name = "Verrrrryyyy llooonngggggg language" };
|
onlineSet.Language = new BeatmapSetOnlineLanguage { Id = 12, Name = "Verrrrryyyy llooonngggggg language" };
|
||||||
online.Result!.Beatmaps.Single().TopTags = Enumerable.Repeat(online.Result!.Beatmaps.Single().TopTags, 3).SelectMany(t => t!).ToArray();
|
onlineSet.Beatmaps.Single().TopTags = Enumerable.Repeat(onlineSet.Beatmaps.Single().TopTags, 3).SelectMany(t => t!).ToArray();
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -127,17 +171,22 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOnlineAvailability()
|
public void TestOnlineAvailability()
|
||||||
{
|
{
|
||||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("online beatmapset", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
AddUntilStep("rating wedge visible", () => wedge.RatingsVisible);
|
AddUntilStep("rating wedge visible", () => wedge.RatingsVisible);
|
||||||
AddUntilStep("fail time wedge visible", () => wedge.FailRetryVisible);
|
AddUntilStep("fail time wedge visible", () => wedge.FailRetryVisible);
|
||||||
AddStep("online beatmapset with local diff", () =>
|
AddStep("online beatmapset with local diff", () =>
|
||||||
{
|
{
|
||||||
var (working, lookupResult) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
working.BeatmapInfo.ResetOnlineInfo();
|
working.BeatmapInfo.ResetOnlineInfo();
|
||||||
|
|
||||||
onlineLookupResult.Value = lookupResult;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddUntilStep("rating wedge hidden", () => !wedge.RatingsVisible);
|
AddUntilStep("rating wedge hidden", () => !wedge.RatingsVisible);
|
||||||
@@ -146,7 +195,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
var (working, _) = createTestBeatmap();
|
var (working, _) = createTestBeatmap();
|
||||||
|
|
||||||
onlineLookupResult.Value = null;
|
currentOnlineSet = null;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddAssert("rating wedge still hidden", () => !wedge.RatingsVisible);
|
AddAssert("rating wedge still hidden", () => !wedge.RatingsVisible);
|
||||||
@@ -156,17 +205,21 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUserTags()
|
public void TestUserTags()
|
||||||
{
|
{
|
||||||
AddStep("user tags", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("user tags", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
AddStep("no user tags", () =>
|
AddStep("no user tags", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Beatmaps.Single().TopTags = null;
|
onlineSet.Beatmaps.Single().TopTags = null;
|
||||||
online.Result!.RelatedTags = null;
|
onlineSet.RelatedTags = null;
|
||||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
|
||||||
|
|
||||||
onlineLookupResult.Value = online;
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -174,60 +227,72 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLoading()
|
public void TestLoading()
|
||||||
{
|
{
|
||||||
|
AddStep("override request handling", () =>
|
||||||
|
{
|
||||||
|
currentOnlineSet = null;
|
||||||
|
|
||||||
|
((DummyAPIAccess)API).HandleRequest = request =>
|
||||||
|
{
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case GetBeatmapSetRequest set:
|
||||||
|
Scheduler.AddDelayed(() => set.TriggerSuccess(currentOnlineSet!), 500);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("set beatmap", () =>
|
AddStep("set beatmap", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
currentOnlineSet = onlineSet;
|
||||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddWaitStep("wait", 5);
|
AddWaitStep("wait", 5);
|
||||||
|
|
||||||
AddStep("set beatmap", () =>
|
AddStep("set beatmap", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.RelatedTags![0].Name = "other/tag";
|
onlineSet.RelatedTags![0].Name = "other/tag";
|
||||||
online.Result!.RelatedTags[1].Name = "another/tag";
|
onlineSet.RelatedTags[1].Name = "another/tag";
|
||||||
online.Result!.RelatedTags[2].Name = "some/tag";
|
onlineSet.RelatedTags[2].Name = "some/tag";
|
||||||
|
|
||||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
currentOnlineSet = onlineSet;
|
||||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddWaitStep("wait", 5);
|
AddWaitStep("wait", 5);
|
||||||
|
|
||||||
AddStep("no user tags", () =>
|
AddStep("no user tags", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Beatmaps.Single().TopTags = null;
|
onlineSet.Beatmaps.Single().TopTags = null;
|
||||||
online.Result!.RelatedTags = null;
|
onlineSet.RelatedTags = null;
|
||||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
|
||||||
|
|
||||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
currentOnlineSet = onlineSet;
|
||||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddWaitStep("wait", 5);
|
AddWaitStep("wait", 5);
|
||||||
|
|
||||||
AddStep("no user tags", () =>
|
AddStep("no user tags", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
online.Result!.Beatmaps.Single().TopTags = null;
|
onlineSet.Beatmaps.Single().TopTags = null;
|
||||||
online.Result!.RelatedTags = null;
|
onlineSet.RelatedTags = null;
|
||||||
working.BeatmapSetInfo.Beatmaps.Single().Metadata.UserTags.Clear();
|
|
||||||
|
|
||||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.InProgress();
|
currentOnlineSet = onlineSet;
|
||||||
Scheduler.AddDelayed(() => onlineLookupResult.Value = online, 500);
|
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
});
|
});
|
||||||
AddWaitStep("wait", 5);
|
AddWaitStep("wait", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (WorkingBeatmap, Screens.SelectV2.SongSelect.BeatmapSetLookupResult) createTestBeatmap()
|
private (WorkingBeatmap, APIBeatmapSet) createTestBeatmap()
|
||||||
{
|
{
|
||||||
var working = CreateWorkingBeatmap(Ruleset.Value);
|
var working = CreateWorkingBeatmap(Ruleset.Value);
|
||||||
var onlineSet = new APIBeatmapSet
|
var onlineSet = new APIBeatmapSet
|
||||||
@@ -281,8 +346,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
|
|
||||||
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
||||||
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
||||||
working.Metadata.UserTags.AddRange(onlineSet.RelatedTags.Select(t => t.Name));
|
return (working, onlineSet);
|
||||||
return (working, Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(onlineSet));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
@@ -42,8 +41,10 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
private BeatmapTitleWedge titleWedge = null!;
|
private BeatmapTitleWedge titleWedge = null!;
|
||||||
private BeatmapTitleWedge.DifficultyDisplay difficultyDisplay => titleWedge.ChildrenOfType<BeatmapTitleWedge.DifficultyDisplay>().Single();
|
private BeatmapTitleWedge.DifficultyDisplay difficultyDisplay => titleWedge.ChildrenOfType<BeatmapTitleWedge.DifficultyDisplay>().Single();
|
||||||
|
|
||||||
[Cached(typeof(IBindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>))]
|
private APIBeatmapSet? currentOnlineSet;
|
||||||
private Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?> onlineLookupResult = new Bindable<Screens.SelectV2.SongSelect.BeatmapSetLookupResult?>();
|
|
||||||
|
[Cached]
|
||||||
|
private RealmPopulatingOnlineLookupSource lookupSource = new RealmPopulatingOnlineLookupSource();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
@@ -57,6 +58,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
|
|
||||||
AddRange(new Drawable[]
|
AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
|
lookupSource,
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@@ -140,18 +142,44 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOnlineAvailability()
|
public void TestOnlineAvailability()
|
||||||
{
|
{
|
||||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("set up request handler", () =>
|
||||||
|
{
|
||||||
|
((DummyAPIAccess)API).HandleRequest = request =>
|
||||||
|
{
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case GetBeatmapSetRequest set:
|
||||||
|
if (set.ID == currentOnlineSet?.OnlineID)
|
||||||
|
{
|
||||||
|
set.TriggerSuccess(currentOnlineSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("online beatmapset", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
||||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||||
AddStep("online beatmapset with local diff", () =>
|
AddStep("online beatmapset with local diff", () =>
|
||||||
{
|
{
|
||||||
var (working, lookupResult) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
working.BeatmapInfo.ResetOnlineInfo();
|
working.BeatmapInfo.ResetOnlineInfo();
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
onlineLookupResult.Value = lookupResult;
|
|
||||||
});
|
});
|
||||||
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
||||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||||
@@ -159,8 +187,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
var (working, _) = createTestBeatmap();
|
var (working, _) = createTestBeatmap();
|
||||||
|
|
||||||
|
currentOnlineSet = null;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
onlineLookupResult.Value = Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(null);
|
|
||||||
});
|
});
|
||||||
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
AddUntilStep("play count is -", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("-"));
|
||||||
AddUntilStep("favourites count is -", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("-"));
|
AddUntilStep("favourites count is -", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("-"));
|
||||||
@@ -177,6 +205,15 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
|
case GetBeatmapSetRequest set:
|
||||||
|
if (set.ID == currentOnlineSet?.OnlineID)
|
||||||
|
{
|
||||||
|
set.TriggerSuccess(currentOnlineSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
case PostBeatmapFavouriteRequest favourite:
|
case PostBeatmapFavouriteRequest favourite:
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@@ -191,8 +228,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("online beatmapset", () => (Beatmap.Value, onlineLookupResult.Value) = createTestBeatmap());
|
AddStep("online beatmapset", () =>
|
||||||
|
{
|
||||||
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
|
Beatmap.Value = working;
|
||||||
|
});
|
||||||
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
AddUntilStep("play count is 10000", () => this.ChildrenOfType<BeatmapTitleWedge.Statistic>().ElementAt(0).Text.ToString(), () => Is.EqualTo("10,000"));
|
||||||
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
AddUntilStep("favourites count is 2345", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("2,345"));
|
||||||
|
|
||||||
@@ -209,13 +251,13 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
AddStep("click favourite button", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().TriggerClick());
|
AddStep("click favourite button", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().TriggerClick());
|
||||||
AddStep("change to another beatmap", () =>
|
AddStep("change to another beatmap", () =>
|
||||||
{
|
{
|
||||||
var (working, online) = createTestBeatmap();
|
var (working, onlineSet) = createTestBeatmap();
|
||||||
online.Result!.FavouriteCount = 9999;
|
onlineSet.FavouriteCount = 9999;
|
||||||
online.Result!.HasFavourited = true;
|
onlineSet.HasFavourited = true;
|
||||||
working.BeatmapSetInfo.OnlineID = online.Result!.OnlineID = 99999;
|
working.BeatmapSetInfo.OnlineID = onlineSet.OnlineID = 99999;
|
||||||
|
|
||||||
|
currentOnlineSet = onlineSet;
|
||||||
Beatmap.Value = working;
|
Beatmap.Value = working;
|
||||||
onlineLookupResult.Value = online;
|
|
||||||
});
|
});
|
||||||
AddStep("allow request to complete", () => resetEvent.Set());
|
AddStep("allow request to complete", () => resetEvent.Set());
|
||||||
AddUntilStep("favourites count is 9999", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("9,999"));
|
AddUntilStep("favourites count is 9999", () => this.ChildrenOfType<BeatmapTitleWedge.FavouriteButton>().Single().Text.ToString(), () => Is.EqualTo("9,999"));
|
||||||
@@ -226,6 +268,15 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
|
case GetBeatmapSetRequest set:
|
||||||
|
if (set.ID == currentOnlineSet?.OnlineID)
|
||||||
|
{
|
||||||
|
set.TriggerSuccess(currentOnlineSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
case PostBeatmapFavouriteRequest favourite:
|
case PostBeatmapFavouriteRequest favourite:
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@@ -299,7 +350,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private (WorkingBeatmap, Screens.SelectV2.SongSelect.BeatmapSetLookupResult) createTestBeatmap()
|
private (WorkingBeatmap, APIBeatmapSet) createTestBeatmap()
|
||||||
{
|
{
|
||||||
var working = CreateWorkingBeatmap(Ruleset.Value);
|
var working = CreateWorkingBeatmap(Ruleset.Value);
|
||||||
var onlineSet = new APIBeatmapSet
|
var onlineSet = new APIBeatmapSet
|
||||||
@@ -320,7 +371,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
|
|
||||||
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
working.BeatmapSetInfo.DateSubmitted = DateTimeOffset.Now;
|
||||||
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
working.BeatmapSetInfo.DateRanked = DateTimeOffset.Now;
|
||||||
return (working, Screens.SelectV2.SongSelect.BeatmapSetLookupResult.Completed(onlineSet));
|
return (working, onlineSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestHitObject : ConvertHitObject;
|
private class TestHitObject : ConvertHitObject;
|
||||||
|
|||||||
@@ -4,13 +4,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
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.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
@@ -24,9 +22,6 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
private FillFlowContainer spreadOutFlow = null!;
|
private FillFlowContainer spreadOutFlow = null!;
|
||||||
private ModDisplay modDisplay = null!;
|
private ModDisplay modDisplay = null!;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesetStore { get; set; } = null!;
|
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
@@ -75,26 +70,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestShowAllMods()
|
public void TestShowAllMods()
|
||||||
{
|
{
|
||||||
createModIconsForRuleset(0);
|
AddStep("create mod icons", () =>
|
||||||
createModIconsForRuleset(1);
|
|
||||||
createModIconsForRuleset(2);
|
|
||||||
createModIconsForRuleset(3);
|
|
||||||
|
|
||||||
AddStep("toggle selected", () =>
|
|
||||||
{
|
{
|
||||||
foreach (var icon in this.ChildrenOfType<ModIcon>())
|
addRange(Ruleset.Value.CreateInstance().CreateAllMods().Select(m =>
|
||||||
icon.Selected.Toggle();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createModIconsForRuleset(int rulesetId)
|
|
||||||
{
|
|
||||||
AddStep($"create mod icons for ruleset {rulesetId}", () =>
|
|
||||||
{
|
|
||||||
spreadOutFlow.Clear();
|
|
||||||
modDisplay.Current.Value = [];
|
|
||||||
|
|
||||||
addRange(rulesetStore.GetRuleset(rulesetId)!.CreateInstance().CreateAllMods().Select(m =>
|
|
||||||
{
|
{
|
||||||
if (m is OsuModFlashlight fl)
|
if (m is OsuModFlashlight fl)
|
||||||
fl.FollowDelay.Value = 1245;
|
fl.FollowDelay.Value = 1245;
|
||||||
@@ -111,6 +89,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
return m;
|
return m;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddStep("toggle selected", () =>
|
||||||
|
{
|
||||||
|
foreach (var icon in this.ChildrenOfType<ModIcon>())
|
||||||
|
icon.Selected.Toggle();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
128
osu.Game/Audio/WelcomeMusicManager.cs
Normal file
128
osu.Game/Audio/WelcomeMusicManager.cs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
// 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 disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Audio
|
||||||
|
{
|
||||||
|
[Cached]
|
||||||
|
public partial class WelcomeMusicManager : Drawable
|
||||||
|
{
|
||||||
|
public event Action<Exception> OnLoadFailure;
|
||||||
|
public event Action OnCategoriesRefreshed;
|
||||||
|
|
||||||
|
public readonly Bindable<IEnumerable<string>> AvailableCategories = new Bindable<IEnumerable<string>>();
|
||||||
|
|
||||||
|
private ITrack preloadedTrack;
|
||||||
|
private List<APIWelcomeMusic> currentTracks;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
private AudioManager audioManager { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager config { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
|
private Bindable<WelcomeMusicMode> musicMode;
|
||||||
|
private Bindable<string> selectedCategory;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
musicMode = config.GetBindable<WelcomeMusicMode>(OsuSetting.WelcomeMusicMode);
|
||||||
|
selectedCategory = config.GetBindable<string>(OsuSetting.WelcomeMusicCategory);
|
||||||
|
fetchCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshCategories() => fetchCategories();
|
||||||
|
|
||||||
|
private void fetchCategories()
|
||||||
|
{
|
||||||
|
var request = new GetMusicCategoriesRequest();
|
||||||
|
request.Success += response =>
|
||||||
|
{
|
||||||
|
var serverCategories = response.Categories ?? Enumerable.Empty<string>();
|
||||||
|
AvailableCategories.Value = serverCategories.ToList();
|
||||||
|
OnCategoriesRefreshed?.Invoke();
|
||||||
|
};
|
||||||
|
request.Failure += exception =>
|
||||||
|
{
|
||||||
|
Logger.Error(exception, "ОШИБКА: Не удалось загрузить категории музыки!");
|
||||||
|
AvailableCategories.Value = new[] { "Не удалось загрузить..." };
|
||||||
|
OnLoadFailure?.Invoke(exception);
|
||||||
|
};
|
||||||
|
api.PerformAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PreloadCurrentTrack()
|
||||||
|
{
|
||||||
|
if (musicMode.Value == WelcomeMusicMode.Default)
|
||||||
|
{
|
||||||
|
preloadedTrack = audioManager.Tracks.Get("Samples/welcome.ogg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(selectedCategory.Value) || selectedCategory.Value.Contains("Не удалось"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var request = new GetWelcomeMusicRequest(selectedCategory.Value);
|
||||||
|
var tcs = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
|
request.Success += response =>
|
||||||
|
{
|
||||||
|
currentTracks = response;
|
||||||
|
tcs.SetResult(true);
|
||||||
|
};
|
||||||
|
request.Failure += exception =>
|
||||||
|
{
|
||||||
|
Logger.Error(exception, "ОШИБКА: Не удалось загрузить список треков!");
|
||||||
|
tcs.SetResult(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
api.PerformAsync(request);
|
||||||
|
await tcs.Task;
|
||||||
|
|
||||||
|
if (currentTracks?.Any() != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var randomTrackInfo = currentTracks[RNG.Next(0, currentTracks.Count)];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
preloadedTrack = audioManager.Tracks.Get(randomTrackInfo.Url);
|
||||||
|
if (preloadedTrack != null)
|
||||||
|
preloadedTrack.Looping = false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error(e, $"ОШИБКА: Не удалось загрузить трек по URL: {randomTrackInfo.Url}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITrack GetPreloadedTrack() => preloadedTrack;
|
||||||
|
|
||||||
|
public void RequestRestart()
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Configuration.Tracking;
|
using osu.Framework.Configuration.Tracking;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps.Drawables.Cards;
|
using osu.Game.Beatmaps.Drawables.Cards;
|
||||||
@@ -42,8 +41,6 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.Ruleset, string.Empty);
|
SetDefault(OsuSetting.Ruleset, string.Empty);
|
||||||
SetDefault(OsuSetting.Skin, SkinInfo.ARGON_SKIN.ToString());
|
SetDefault(OsuSetting.Skin, SkinInfo.ARGON_SKIN.ToString());
|
||||||
|
|
||||||
SetDefault(OsuSetting.MenuCookieColor, Colour4.FromHex(@"ff66ba"));
|
|
||||||
|
|
||||||
SetDefault(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Local);
|
SetDefault(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Local);
|
||||||
SetDefault(OsuSetting.BeatmapLeaderboardSortMode, LeaderboardSortMode.Score);
|
SetDefault(OsuSetting.BeatmapLeaderboardSortMode, LeaderboardSortMode.Score);
|
||||||
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
SetDefault(OsuSetting.BeatmapDetailModsFilter, false);
|
||||||
@@ -68,7 +65,6 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
SetDefault(OsuSetting.ToolbarClockDisplayMode, ToolbarClockDisplayMode.Full);
|
SetDefault(OsuSetting.ToolbarClockDisplayMode, ToolbarClockDisplayMode.Full);
|
||||||
|
|
||||||
SetDefault(OsuSetting.ForceLegacySongSelect, false);
|
|
||||||
SetDefault(OsuSetting.SongSelectBackgroundBlur, false);
|
SetDefault(OsuSetting.SongSelectBackgroundBlur, false);
|
||||||
|
|
||||||
// Online settings
|
// Online settings
|
||||||
@@ -198,7 +194,6 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
SetDefault(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
SetDefault(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
||||||
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Never);
|
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Never);
|
||||||
SetDefault(OsuSetting.UseSeasonalBackgroundsV2, true);
|
|
||||||
|
|
||||||
SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full);
|
SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full);
|
||||||
|
|
||||||
@@ -218,6 +213,8 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.MultiplayerShowInProgressFilter, true);
|
SetDefault(OsuSetting.MultiplayerShowInProgressFilter, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.LastProcessedMetadataId, -1);
|
SetDefault(OsuSetting.LastProcessedMetadataId, -1);
|
||||||
|
SetDefault(OsuSetting.WelcomeMusicMode, WelcomeMusicMode.Default);
|
||||||
|
SetDefault(OsuSetting.WelcomeMusicCategory, "Default");
|
||||||
|
|
||||||
SetDefault(OsuSetting.ComboColourNormalisationAmount, 0.2f, 0f, 1f, 0.01f);
|
SetDefault(OsuSetting.ComboColourNormalisationAmount, 0.2f, 0f, 1f, 0.01f);
|
||||||
SetDefault(OsuSetting.UserOnlineStatus, UserStatus.Online);
|
SetDefault(OsuSetting.UserOnlineStatus, UserStatus.Online);
|
||||||
@@ -387,6 +384,8 @@ namespace osu.Game.Configuration
|
|||||||
AudioOffset,
|
AudioOffset,
|
||||||
|
|
||||||
VolumeInactive,
|
VolumeInactive,
|
||||||
|
WelcomeMusicMode,
|
||||||
|
WelcomeMusicCategory,
|
||||||
MenuMusic,
|
MenuMusic,
|
||||||
MenuVoice,
|
MenuVoice,
|
||||||
MenuTips,
|
MenuTips,
|
||||||
@@ -410,7 +409,6 @@ namespace osu.Game.Configuration
|
|||||||
ChatDisplayHeight,
|
ChatDisplayHeight,
|
||||||
BeatmapListingCardSize,
|
BeatmapListingCardSize,
|
||||||
ToolbarClockDisplayMode,
|
ToolbarClockDisplayMode,
|
||||||
ForceLegacySongSelect,
|
|
||||||
SongSelectBackgroundBlur,
|
SongSelectBackgroundBlur,
|
||||||
Version,
|
Version,
|
||||||
ShowFirstRunSetup,
|
ShowFirstRunSetup,
|
||||||
@@ -418,7 +416,6 @@ namespace osu.Game.Configuration
|
|||||||
Skin,
|
Skin,
|
||||||
ScreenshotFormat,
|
ScreenshotFormat,
|
||||||
ScreenshotCaptureMenuCursor,
|
ScreenshotCaptureMenuCursor,
|
||||||
MenuCookieColor,
|
|
||||||
BeatmapSkins,
|
BeatmapSkins,
|
||||||
BeatmapColours,
|
BeatmapColours,
|
||||||
BeatmapHitsounds,
|
BeatmapHitsounds,
|
||||||
@@ -443,7 +440,6 @@ namespace osu.Game.Configuration
|
|||||||
MenuBackgroundSource,
|
MenuBackgroundSource,
|
||||||
GameplayDisableWinKey,
|
GameplayDisableWinKey,
|
||||||
SeasonalBackgroundMode,
|
SeasonalBackgroundMode,
|
||||||
UseSeasonalBackgroundsV2, // TODO: add migrations
|
|
||||||
BackgroundCategory,
|
BackgroundCategory,
|
||||||
EditorWaveformOpacity,
|
EditorWaveformOpacity,
|
||||||
EditorShowHitMarkers,
|
EditorShowHitMarkers,
|
||||||
|
|||||||
11
osu.Game/Configuration/WelcomeMusicMode.cs
Normal file
11
osu.Game/Configuration/WelcomeMusicMode.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Configuration
|
||||||
|
{
|
||||||
|
public enum WelcomeMusicMode
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -558,15 +558,9 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
Logger.Log("Querying for beatmap sets that contain missing submission/rank date...");
|
Logger.Log("Querying for beatmap sets that contain missing submission/rank date...");
|
||||||
|
|
||||||
// find all ranked beatmap sets with missing date ranked or date submitted that have at least one difficulty ranked as well.
|
|
||||||
// the reason for checking ranked status of the difficulties is that they can be locally modified or unknown too, and for those the lookup is likely to fail.
|
|
||||||
// this is because metadata lookups are primarily based on file hash, so they will fail to match if the beatmap does not match the online version
|
|
||||||
// (which is likely to be the case if the beatmap is locally modified or unknown).
|
|
||||||
// that said, one difficulty in ranked state is enough for the backpopulation to work.
|
|
||||||
HashSet<Guid> beatmapSetIds = realmAccess.Run(r => new HashSet<Guid>(
|
HashSet<Guid> beatmapSetIds = realmAccess.Run(r => new HashSet<Guid>(
|
||||||
r.All<BeatmapSetInfo>()
|
r.All<BeatmapSetInfo>()
|
||||||
.Filter($@"{nameof(BeatmapSetInfo.StatusInt)} > 0 && ({nameof(BeatmapSetInfo.DateRanked)} == null || {nameof(BeatmapSetInfo.DateSubmitted)} == null) "
|
.Where(b => b.StatusInt > 0 && (b.DateRanked == null || b.DateSubmitted == null))
|
||||||
+ $@"&& ANY {nameof(BeatmapSetInfo.Beatmaps)}.{nameof(BeatmapInfo.StatusInt)} > 0")
|
|
||||||
.AsEnumerable()
|
.AsEnumerable()
|
||||||
.Select(b => b.ID)));
|
.Select(b => b.ID)));
|
||||||
|
|
||||||
@@ -597,7 +591,11 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
BeatmapSetInfo beatmapSet = r.Find<BeatmapSetInfo>(id)!;
|
BeatmapSetInfo beatmapSet = r.Find<BeatmapSetInfo>(id)!;
|
||||||
|
|
||||||
var beatmap = beatmapSet.Beatmaps.First(b => b.Status >= BeatmapOnlineStatus.Ranked);
|
// we want any ranked representative of the set.
|
||||||
|
// the reason for checking ranked status of the difficulty is that it can be locally modified,
|
||||||
|
// at which point the lookup will fail - but there might still be another unmodified difficulty on which it will work.
|
||||||
|
if (beatmapSet.Beatmaps.FirstOrDefault(b => b.Status >= BeatmapOnlineStatus.Ranked) is not BeatmapInfo beatmap)
|
||||||
|
return false;
|
||||||
|
|
||||||
bool lookupSucceeded = localMetadataSource.TryLookup(beatmap, out var result);
|
bool lookupSucceeded = localMetadataSource.TryLookup(beatmap, out var result);
|
||||||
|
|
||||||
@@ -727,7 +725,7 @@ namespace osu.Game.Database
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Log(@$"Failed to update user tags for beatmap {id}: {e}");
|
Logger.Log(@$"Failed to update ranked/submitted dates for beatmap set {id}: {e}");
|
||||||
++failedCount;
|
++failedCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,19 +33,19 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
private Bindable<bool> useSeasonalBackgrounds;
|
private Bindable<SeasonalBackgroundMode> backgroundMode;
|
||||||
private Bindable<string> selectedCategory;
|
private Bindable<string> selectedCategory;
|
||||||
private Bindable<APISeasonalBackgrounds> currentBackgrounds;
|
private Bindable<APISeasonalBackgrounds> currentBackgrounds;
|
||||||
|
|
||||||
private int currentBackgroundIndex;
|
private int currentBackgroundIndex;
|
||||||
|
|
||||||
private bool shouldShowCustomBackgrounds => useSeasonalBackgrounds.Value;
|
private bool shouldShowCustomBackgrounds => backgroundMode.Value != SeasonalBackgroundMode.Never;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, SessionStatics sessionStatics)
|
private void load(OsuConfigManager config, SessionStatics sessionStatics)
|
||||||
{
|
{
|
||||||
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
|
backgroundMode = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
||||||
useSeasonalBackgrounds.BindValueChanged(_ => BackgroundChanged?.Invoke());
|
backgroundMode.BindValueChanged(_ => BackgroundChanged?.Invoke());
|
||||||
|
|
||||||
selectedCategory = config.GetBindable<string>(OsuSetting.BackgroundCategory);
|
selectedCategory = config.GetBindable<string>(OsuSetting.BackgroundCategory);
|
||||||
selectedCategory.BindValueChanged(_ => fetchBackgroundsForSelectedCategory());
|
selectedCategory.BindValueChanged(_ => fetchBackgroundsForSelectedCategory());
|
||||||
@@ -53,18 +53,18 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
currentBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
currentBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
||||||
|
|
||||||
if (shouldShowCustomBackgrounds)
|
if (shouldShowCustomBackgrounds)
|
||||||
fetchCategories(true);
|
fetchCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Public method to trigger a refresh of categories from the UI.
|
/// Public method to trigger a refresh of categories from the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RefreshCategories(bool ignoreSuccess = false)
|
public void RefreshCategories()
|
||||||
{
|
{
|
||||||
fetchCategories(ignoreSuccess);
|
fetchCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchCategories(bool ignoreSuccess = false)
|
private void fetchCategories()
|
||||||
{
|
{
|
||||||
if (!shouldShowCustomBackgrounds) return;
|
if (!shouldShowCustomBackgrounds) return;
|
||||||
|
|
||||||
@@ -74,28 +74,20 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
{
|
{
|
||||||
var serverCategories = response.Categories ?? Enumerable.Empty<string>();
|
var serverCategories = response.Categories ?? Enumerable.Empty<string>();
|
||||||
|
|
||||||
AvailableCategories.Value = serverCategories.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
AvailableCategories.Value = new[] { "Default" }.Concat(serverCategories)
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
if (!AvailableCategories.Value.Any())
|
|
||||||
{
|
|
||||||
selectedCategory.Value = "";
|
|
||||||
return; // we don't have any categories!!!
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!AvailableCategories.Value.Contains(selectedCategory.Value))
|
if (!AvailableCategories.Value.Contains(selectedCategory.Value))
|
||||||
selectedCategory.Value = AvailableCategories.Value.Contains("Default")
|
selectedCategory.Value = "Default";
|
||||||
? "Default"
|
else
|
||||||
: AvailableCategories.Value.ElementAt(0);
|
fetchBackgroundsForSelectedCategory();
|
||||||
|
|
||||||
fetchBackgroundsForSelectedCategory();
|
OnCategoriesRefreshed?.Invoke();
|
||||||
|
|
||||||
if (!ignoreSuccess)
|
|
||||||
OnCategoriesRefreshed?.Invoke();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
request.Failure += exception =>
|
request.Failure += exception =>
|
||||||
{
|
{
|
||||||
AvailableCategories.Value = Array.Empty<string>();
|
AvailableCategories.Value = new[] { "Íå óäàëîñü çàãðóçèòü..." };
|
||||||
OnLoadFailure?.Invoke(exception);
|
OnLoadFailure?.Invoke(exception);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,6 +98,13 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
{
|
{
|
||||||
if (!shouldShowCustomBackgrounds) return;
|
if (!shouldShowCustomBackgrounds) return;
|
||||||
|
|
||||||
|
if (AvailableCategories.Value.Count() == 1 && AvailableCategories.Value.First().Contains("Íå óäàëîñü"))
|
||||||
|
{
|
||||||
|
currentBackgrounds.Value = new APISeasonalBackgrounds { Backgrounds = new List<APISeasonalBackground>() };
|
||||||
|
BackgroundChanged?.Invoke();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string categoryToFetch = selectedCategory.Value == "Default" ? null : selectedCategory.Value;
|
string categoryToFetch = selectedCategory.Value == "Default" ? null : selectedCategory.Value;
|
||||||
var request = new GetSeasonalBackgroundsRequest(categoryToFetch);
|
var request = new GetSeasonalBackgroundsRequest(categoryToFetch);
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,27 @@ namespace osu.Game.Graphics
|
|||||||
public static IconUsage InsaneMania => get(0xe027);
|
public static IconUsage InsaneMania => get(0xe027);
|
||||||
public static IconUsage ExpertMania => get(0xe028);
|
public static IconUsage ExpertMania => get(0xe028);
|
||||||
|
|
||||||
|
// mod icons
|
||||||
|
public static IconUsage ModPerfect => get(0xe049);
|
||||||
|
public static IconUsage ModAutopilot => get(0xe03a);
|
||||||
|
public static IconUsage ModAuto => get(0xe03b);
|
||||||
|
public static IconUsage ModCinema => get(0xe03c);
|
||||||
|
public static IconUsage ModDoubleTime => get(0xe03d);
|
||||||
|
public static IconUsage ModEasy => get(0xe03e);
|
||||||
|
public static IconUsage ModFlashlight => get(0xe03f);
|
||||||
|
public static IconUsage ModHalftime => get(0xe040);
|
||||||
|
public static IconUsage ModHardRock => get(0xe041);
|
||||||
|
public static IconUsage ModHidden => get(0xe042);
|
||||||
|
public static IconUsage ModNightcore => get(0xe043);
|
||||||
|
public static IconUsage ModNoFail => get(0xe044);
|
||||||
|
public static IconUsage ModRelax => get(0xe045);
|
||||||
|
public static IconUsage ModSpunOut => get(0xe046);
|
||||||
|
public static IconUsage ModSuddenDeath => get(0xe047);
|
||||||
|
public static IconUsage ModTarget => get(0xe048);
|
||||||
|
|
||||||
|
// Use "Icons/BeatmapDetails/mod-icon" instead
|
||||||
|
// public static IconUsage ModBg => Get(0xe04a);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region New single-file-based icons
|
#region New single-file-based icons
|
||||||
@@ -160,88 +181,6 @@ namespace osu.Game.Graphics
|
|||||||
public static IconUsage Tortoise => get(OsuIconMapping.Tortoise);
|
public static IconUsage Tortoise => get(OsuIconMapping.Tortoise);
|
||||||
public static IconUsage Hare => get(OsuIconMapping.Hare);
|
public static IconUsage Hare => get(OsuIconMapping.Hare);
|
||||||
|
|
||||||
// mod icons
|
|
||||||
|
|
||||||
public static IconUsage ModNoMod => get(OsuIconMapping.ModNoMod);
|
|
||||||
|
|
||||||
/*
|
|
||||||
can be regenerated semi-automatically using osu-web's mod database via
|
|
||||||
|
|
||||||
$ jq -r '.[].Mods[].Name' mods.json | sort | uniq | \
|
|
||||||
sed 's/ //g' | \
|
|
||||||
awk '{print "public static IconUsage Mod" $0 " => get(OsuIconMapping.Mod" $0 ");"}' | pbcopy
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static IconUsage ModAccuracyChallenge => get(OsuIconMapping.ModAccuracyChallenge);
|
|
||||||
public static IconUsage ModAdaptiveSpeed => get(OsuIconMapping.ModAdaptiveSpeed);
|
|
||||||
public static IconUsage ModAlternate => get(OsuIconMapping.ModAlternate);
|
|
||||||
public static IconUsage ModApproachDifferent => get(OsuIconMapping.ModApproachDifferent);
|
|
||||||
public static IconUsage ModAutopilot => get(OsuIconMapping.ModAutopilot);
|
|
||||||
public static IconUsage ModAutoplay => get(OsuIconMapping.ModAutoplay);
|
|
||||||
public static IconUsage ModBarrelRoll => get(OsuIconMapping.ModBarrelRoll);
|
|
||||||
public static IconUsage ModBlinds => get(OsuIconMapping.ModBlinds);
|
|
||||||
public static IconUsage ModBloom => get(OsuIconMapping.ModBloom);
|
|
||||||
public static IconUsage ModBubbles => get(OsuIconMapping.ModBubbles);
|
|
||||||
public static IconUsage ModCinema => get(OsuIconMapping.ModCinema);
|
|
||||||
public static IconUsage ModClassic => get(OsuIconMapping.ModClassic);
|
|
||||||
public static IconUsage ModConstantSpeed => get(OsuIconMapping.ModConstantSpeed);
|
|
||||||
public static IconUsage ModCover => get(OsuIconMapping.ModCover);
|
|
||||||
public static IconUsage ModDaycore => get(OsuIconMapping.ModDaycore);
|
|
||||||
public static IconUsage ModDeflate => get(OsuIconMapping.ModDeflate);
|
|
||||||
public static IconUsage ModDepth => get(OsuIconMapping.ModDepth);
|
|
||||||
public static IconUsage ModDifficultyAdjust => get(OsuIconMapping.ModDifficultyAdjust);
|
|
||||||
public static IconUsage ModDoubleTime => get(OsuIconMapping.ModDoubleTime);
|
|
||||||
public static IconUsage ModDualStages => get(OsuIconMapping.ModDualStages);
|
|
||||||
public static IconUsage ModEasy => get(OsuIconMapping.ModEasy);
|
|
||||||
public static IconUsage ModEightKeys => get(OsuIconMapping.ModEightKeys);
|
|
||||||
public static IconUsage ModFadeIn => get(OsuIconMapping.ModFadeIn);
|
|
||||||
public static IconUsage ModFiveKeys => get(OsuIconMapping.ModFiveKeys);
|
|
||||||
public static IconUsage ModFlashlight => get(OsuIconMapping.ModFlashlight);
|
|
||||||
public static IconUsage ModFloatingFruits => get(OsuIconMapping.ModFloatingFruits);
|
|
||||||
public static IconUsage ModFourKeys => get(OsuIconMapping.ModFourKeys);
|
|
||||||
public static IconUsage ModFreezeFrame => get(OsuIconMapping.ModFreezeFrame);
|
|
||||||
public static IconUsage ModGrow => get(OsuIconMapping.ModGrow);
|
|
||||||
public static IconUsage ModHalfTime => get(OsuIconMapping.ModHalfTime);
|
|
||||||
public static IconUsage ModHardRock => get(OsuIconMapping.ModHardRock);
|
|
||||||
public static IconUsage ModHidden => get(OsuIconMapping.ModHidden);
|
|
||||||
public static IconUsage ModHoldOff => get(OsuIconMapping.ModHoldOff);
|
|
||||||
public static IconUsage ModInvert => get(OsuIconMapping.ModInvert);
|
|
||||||
public static IconUsage ModMagnetised => get(OsuIconMapping.ModMagnetised);
|
|
||||||
public static IconUsage ModMirror => get(OsuIconMapping.ModMirror);
|
|
||||||
public static IconUsage ModMovingFast => get(OsuIconMapping.ModMovingFast);
|
|
||||||
public static IconUsage ModMuted => get(OsuIconMapping.ModMuted);
|
|
||||||
public static IconUsage ModNightcore => get(OsuIconMapping.ModNightcore);
|
|
||||||
public static IconUsage ModNineKeys => get(OsuIconMapping.ModNineKeys);
|
|
||||||
public static IconUsage ModNoFail => get(OsuIconMapping.ModNoFail);
|
|
||||||
public static IconUsage ModNoRelease => get(OsuIconMapping.ModNoRelease);
|
|
||||||
public static IconUsage ModNoScope => get(OsuIconMapping.ModNoScope);
|
|
||||||
public static IconUsage ModOneKey => get(OsuIconMapping.ModOneKey);
|
|
||||||
public static IconUsage ModPerfect => get(OsuIconMapping.ModPerfect);
|
|
||||||
public static IconUsage ModRandom => get(OsuIconMapping.ModRandom);
|
|
||||||
public static IconUsage ModRelax => get(OsuIconMapping.ModRelax);
|
|
||||||
public static IconUsage ModRepel => get(OsuIconMapping.ModRepel);
|
|
||||||
public static IconUsage ModScoreV2 => get(OsuIconMapping.ModScoreV2);
|
|
||||||
public static IconUsage ModSevenKeys => get(OsuIconMapping.ModSevenKeys);
|
|
||||||
public static IconUsage ModSimplifiedRhythm => get(OsuIconMapping.ModSimplifiedRhythm);
|
|
||||||
public static IconUsage ModSingleTap => get(OsuIconMapping.ModSingleTap);
|
|
||||||
public static IconUsage ModSixKeys => get(OsuIconMapping.ModSixKeys);
|
|
||||||
public static IconUsage ModSpinIn => get(OsuIconMapping.ModSpinIn);
|
|
||||||
public static IconUsage ModSpunOut => get(OsuIconMapping.ModSpunOut);
|
|
||||||
public static IconUsage ModStrictTracking => get(OsuIconMapping.ModStrictTracking);
|
|
||||||
public static IconUsage ModSuddenDeath => get(OsuIconMapping.ModSuddenDeath);
|
|
||||||
public static IconUsage ModSwap => get(OsuIconMapping.ModSwap);
|
|
||||||
public static IconUsage ModSynesthesia => get(OsuIconMapping.ModSynesthesia);
|
|
||||||
public static IconUsage ModTargetPractice => get(OsuIconMapping.ModTargetPractice);
|
|
||||||
public static IconUsage ModTenKeys => get(OsuIconMapping.ModTenKeys);
|
|
||||||
public static IconUsage ModThreeKeys => get(OsuIconMapping.ModThreeKeys);
|
|
||||||
public static IconUsage ModTouchDevice => get(OsuIconMapping.ModTouchDevice);
|
|
||||||
public static IconUsage ModTraceable => get(OsuIconMapping.ModTraceable);
|
|
||||||
public static IconUsage ModTransform => get(OsuIconMapping.ModTransform);
|
|
||||||
public static IconUsage ModTwoKeys => get(OsuIconMapping.ModTwoKeys);
|
|
||||||
public static IconUsage ModWiggle => get(OsuIconMapping.ModWiggle);
|
|
||||||
public static IconUsage ModWindDown => get(OsuIconMapping.ModWindDown);
|
|
||||||
public static IconUsage ModWindUp => get(OsuIconMapping.ModWindUp);
|
|
||||||
|
|
||||||
private static IconUsage get(OsuIconMapping glyph) => new IconUsage((char)glyph, FONT_NAME);
|
private static IconUsage get(OsuIconMapping glyph) => new IconUsage((char)glyph, FONT_NAME);
|
||||||
|
|
||||||
private enum OsuIconMapping
|
private enum OsuIconMapping
|
||||||
@@ -461,224 +400,6 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
[Description(@"hare")]
|
[Description(@"hare")]
|
||||||
Hare,
|
Hare,
|
||||||
|
|
||||||
// mod icons
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-no-mod")]
|
|
||||||
ModNoMod,
|
|
||||||
|
|
||||||
/*
|
|
||||||
rest can be regenerated semi-automatically using osu-web's mod database via
|
|
||||||
$ jq -r '.[].Mods[].Name' mods.json | sort | uniq | \
|
|
||||||
awk '{kebab = $0; gsub(" ", "-", kebab); pascal = $0; gsub(" ", "", pascal); print "[Description(@\"Mods/mod-" tolower(kebab) "\")]\nMod" pascal ",\n" }' | pbcopy
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-accuracy-challenge")]
|
|
||||||
ModAccuracyChallenge,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-adaptive-speed")]
|
|
||||||
ModAdaptiveSpeed,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-alternate")]
|
|
||||||
ModAlternate,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-approach-different")]
|
|
||||||
ModApproachDifferent,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-autopilot")]
|
|
||||||
ModAutopilot,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-autoplay")]
|
|
||||||
ModAutoplay,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-barrel-roll")]
|
|
||||||
ModBarrelRoll,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-blinds")]
|
|
||||||
ModBlinds,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-bloom")]
|
|
||||||
ModBloom,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-bubbles")]
|
|
||||||
ModBubbles,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-cinema")]
|
|
||||||
ModCinema,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-classic")]
|
|
||||||
ModClassic,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-constant-speed")]
|
|
||||||
ModConstantSpeed,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-cover")]
|
|
||||||
ModCover,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-daycore")]
|
|
||||||
ModDaycore,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-deflate")]
|
|
||||||
ModDeflate,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-depth")]
|
|
||||||
ModDepth,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-difficulty-adjust")]
|
|
||||||
ModDifficultyAdjust,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-double-time")]
|
|
||||||
ModDoubleTime,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-dual-stages")]
|
|
||||||
ModDualStages,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-easy")]
|
|
||||||
ModEasy,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-eight-keys")]
|
|
||||||
ModEightKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-fade-in")]
|
|
||||||
ModFadeIn,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-five-keys")]
|
|
||||||
ModFiveKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-flashlight")]
|
|
||||||
ModFlashlight,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-floating-fruits")]
|
|
||||||
ModFloatingFruits,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-four-keys")]
|
|
||||||
ModFourKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-freeze-frame")]
|
|
||||||
ModFreezeFrame,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-grow")]
|
|
||||||
ModGrow,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-half-time")]
|
|
||||||
ModHalfTime,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-hard-rock")]
|
|
||||||
ModHardRock,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-hidden")]
|
|
||||||
ModHidden,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-hold-off")]
|
|
||||||
ModHoldOff,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-invert")]
|
|
||||||
ModInvert,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-magnetised")]
|
|
||||||
ModMagnetised,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-mirror")]
|
|
||||||
ModMirror,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-moving-fast")]
|
|
||||||
ModMovingFast,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-muted")]
|
|
||||||
ModMuted,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-nightcore")]
|
|
||||||
ModNightcore,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-nine-keys")]
|
|
||||||
ModNineKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-no-fail")]
|
|
||||||
ModNoFail,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-no-release")]
|
|
||||||
ModNoRelease,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-no-scope")]
|
|
||||||
ModNoScope,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-one-key")]
|
|
||||||
ModOneKey,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-perfect")]
|
|
||||||
ModPerfect,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-random")]
|
|
||||||
ModRandom,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-relax")]
|
|
||||||
ModRelax,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-repel")]
|
|
||||||
ModRepel,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-score-v2")]
|
|
||||||
ModScoreV2,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-seven-keys")]
|
|
||||||
ModSevenKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-simplified-rhythm")]
|
|
||||||
ModSimplifiedRhythm,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-single-tap")]
|
|
||||||
ModSingleTap,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-six-keys")]
|
|
||||||
ModSixKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-spin-in")]
|
|
||||||
ModSpinIn,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-spun-out")]
|
|
||||||
ModSpunOut,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-strict-tracking")]
|
|
||||||
ModStrictTracking,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-sudden-death")]
|
|
||||||
ModSuddenDeath,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-swap")]
|
|
||||||
ModSwap,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-synesthesia")]
|
|
||||||
ModSynesthesia,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-target-practice")]
|
|
||||||
ModTargetPractice,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-ten-keys")]
|
|
||||||
ModTenKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-three-keys")]
|
|
||||||
ModThreeKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-touch-device")]
|
|
||||||
ModTouchDevice,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-traceable")]
|
|
||||||
ModTraceable,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-transform")]
|
|
||||||
ModTransform,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-two-keys")]
|
|
||||||
ModTwoKeys,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-wiggle")]
|
|
||||||
ModWiggle,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-wind-down")]
|
|
||||||
ModWindDown,
|
|
||||||
|
|
||||||
[Description(@"Mods/mod-wind-up")]
|
|
||||||
ModWindUp,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OsuIconStore : ITextureStore, ITexturedGlyphLookupStore
|
public class OsuIconStore : ITextureStore, ITexturedGlyphLookupStore
|
||||||
|
|||||||
@@ -184,11 +184,6 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString SelectedMods => new TranslatableString(getKey(@"selected_mods"), @"Selected Mods");
|
public static LocalisableString SelectedMods => new TranslatableString(getKey(@"selected_mods"), @"Selected Mods");
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// "Use legacy song select (SelectV1)"
|
|
||||||
/// </summary>
|
|
||||||
public static LocalisableString ForceLegacySongSelect => new TranslatableString(getKey(@"force_select_v1"), @"Use legacy song select (SelectV1)");
|
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
osu.Game/Online/API/Requests/GetMusicCategoriesRequest.cs
Normal file
12
osu.Game/Online/API/Requests/GetMusicCategoriesRequest.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// 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.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetMusicCategoriesRequest : APIRequest<APIBackgroundCategories>
|
||||||
|
{
|
||||||
|
protected override string Target => @"https://osu.jvnko.boats/welcome-music/categories";
|
||||||
|
}
|
||||||
|
}
|
||||||
21
osu.Game/Online/API/Requests/GetWelcomeMusicRequest.cs
Normal file
21
osu.Game/Online/API/Requests/GetWelcomeMusicRequest.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetWelcomeMusicRequest : APIRequest<List<APIWelcomeMusic>>
|
||||||
|
{
|
||||||
|
private readonly string category;
|
||||||
|
|
||||||
|
public GetWelcomeMusicRequest(string category)
|
||||||
|
{
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $"https://osu.jvnko.boats/welcome-music/list?category={WebUtility.UrlEncode(category)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
17
osu.Game/Online/API/Requests/Responses/APIWelcomeMusic.cs
Normal file
17
osu.Game/Online/API/Requests/Responses/APIWelcomeMusic.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// 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 Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
// Описывает один трек, как он приходит с сервера
|
||||||
|
public class APIWelcomeMusic
|
||||||
|
{
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("url")]
|
||||||
|
public string? Url { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ using osu.Framework.Logging;
|
|||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Collections;
|
using osu.Game.Collections;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
@@ -170,8 +171,11 @@ namespace osu.Game
|
|||||||
[Cached]
|
[Cached]
|
||||||
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
|
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
|
||||||
|
|
||||||
|
// --- ÍÀØÈ ÍÎÂÛÅ ÊÎÌÏÎÍÅÍÒÛ ---
|
||||||
[Cached]
|
[Cached]
|
||||||
private SeasonalBackgroundLoader seasonalBackgroundLoader;
|
private readonly SeasonalBackgroundLoader backgroundLoader;
|
||||||
|
[Cached]
|
||||||
|
private readonly WelcomeMusicManager musicManager;
|
||||||
|
|
||||||
protected SentryLogger SentryLogger;
|
protected SentryLogger SentryLogger;
|
||||||
|
|
||||||
@@ -253,6 +257,12 @@ namespace osu.Game
|
|||||||
|
|
||||||
public OsuGame(string[] args = null)
|
public OsuGame(string[] args = null)
|
||||||
{
|
{
|
||||||
|
// --- ÑÎÇÄÀÅÌ ÍÀØÈ ÊÎÌÏÎÍÅÍÒÛ È ÏÎÄÏÈÑÛÂÀÅÌÑß ÍÀ ÑÎÁÛÒÈß ---
|
||||||
|
backgroundLoader = new SeasonalBackgroundLoader();
|
||||||
|
backgroundLoader.OnLoadFailure += handleBackgroundLoadFailure;
|
||||||
|
backgroundLoader.OnCategoriesRefreshed += handleCategoriesRefreshed;
|
||||||
|
musicManager = new WelcomeMusicManager();
|
||||||
|
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
|
||||||
Logger.NewEntry += forwardGeneralLogToNotifications;
|
Logger.NewEntry += forwardGeneralLogToNotifications;
|
||||||
@@ -267,8 +277,6 @@ namespace osu.Game
|
|||||||
tabletLogNotifyOnError = true;
|
tabletLogNotifyOnError = true;
|
||||||
}, true);
|
}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
initializeSeasonalBackgrounds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IOverlayManager
|
#region IOverlayManager
|
||||||
@@ -407,6 +415,17 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void handleCategoriesRefreshed()
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
Notifications?.Post(new SimpleNotification
|
||||||
|
{
|
||||||
|
Text = "Ñïèñîê êàòåãîðèé ôîíîâ îáíîâëåí.",
|
||||||
|
Icon = FontAwesome.Solid.CheckCircle
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
@@ -457,7 +476,8 @@ namespace osu.Game
|
|||||||
IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);
|
IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);
|
||||||
|
|
||||||
Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade);
|
Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade);
|
||||||
|
dependencies.CacheAs(musicManager);
|
||||||
|
Add(musicManager);
|
||||||
SelectedMods.BindValueChanged(modsChanged);
|
SelectedMods.BindValueChanged(modsChanged);
|
||||||
Beatmap.BindValueChanged(beatmapChanged, true);
|
Beatmap.BindValueChanged(beatmapChanged, true);
|
||||||
configUserActivity.BindValueChanged(_ => updateWindowTitle());
|
configUserActivity.BindValueChanged(_ => updateWindowTitle());
|
||||||
@@ -1238,7 +1258,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
loadComponentSingleFile(screenshotManager, Add);
|
loadComponentSingleFile(screenshotManager, Add);
|
||||||
|
|
||||||
loadComponentSingleFile(seasonalBackgroundLoader, Add);
|
loadComponentSingleFile(backgroundLoader, Add);
|
||||||
|
|
||||||
// dependency on notification overlay, dependent by settings overlay
|
// dependency on notification overlay, dependent by settings overlay
|
||||||
loadComponentSingleFile(CreateUpdateManager(), Add, true);
|
loadComponentSingleFile(CreateUpdateManager(), Add, true);
|
||||||
@@ -1273,7 +1293,12 @@ namespace osu.Game
|
|||||||
}, rightFloatingOverlayContent.Add, true);
|
}, rightFloatingOverlayContent.Add, true);
|
||||||
|
|
||||||
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
||||||
loadComponentSingleFile<IDialogOverlay>(new DialogOverlay(), topMostOverlayContent.Add, true);
|
|
||||||
|
var dialogOverlay = new DialogOverlay();
|
||||||
|
dependencies.CacheAs<IDialogOverlay>(dialogOverlay);
|
||||||
|
dependencies.Cache(dialogOverlay);
|
||||||
|
loadComponentSingleFile(dialogOverlay, topMostOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(new MedalOverlay(), topMostOverlayContent.Add);
|
loadComponentSingleFile(new MedalOverlay(), topMostOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add);
|
loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add);
|
||||||
@@ -1341,6 +1366,18 @@ namespace osu.Game
|
|||||||
handleStartupImport();
|
handleStartupImport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleBackgroundLoadFailure(Exception exception)
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
Notifications?.Post(new SimpleErrorNotification
|
||||||
|
{
|
||||||
|
Text = ButtonSystemStrings.SeasonalBackgroundsFail,
|
||||||
|
Icon = FontAwesome.Solid.ExclamationTriangle,
|
||||||
|
Transient = true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
private void handleBackButton()
|
private void handleBackButton()
|
||||||
{
|
{
|
||||||
// TODO: this is SUPER SUPER bad.
|
// TODO: this is SUPER SUPER bad.
|
||||||
@@ -1477,40 +1514,6 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeSeasonalBackgrounds()
|
|
||||||
{
|
|
||||||
seasonalBackgroundLoader = new SeasonalBackgroundLoader();
|
|
||||||
seasonalBackgroundLoader.OnCategoriesRefreshed += handleCategoriesRefreshed;
|
|
||||||
seasonalBackgroundLoader.OnLoadFailure += handleBackgroundLoadFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleCategoriesRefreshed()
|
|
||||||
{
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
Notifications?.Post(new SimpleNotification
|
|
||||||
{
|
|
||||||
Text = ButtonSystemStrings.SeasonalBackgroundsRefreshed,
|
|
||||||
Icon = FontAwesome.Solid.CheckCircle,
|
|
||||||
Transient = true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleBackgroundLoadFailure(Exception exception)
|
|
||||||
{
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
Notifications?.Post(new SimpleErrorNotification
|
|
||||||
{
|
|
||||||
Text = ButtonSystemStrings.SeasonalBackgroundsFail,
|
|
||||||
Icon = FontAwesome.Solid.ExclamationTriangle,
|
|
||||||
Transient = true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Task asyncLoadStream;
|
private Task asyncLoadStream;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
||||||
{
|
{
|
||||||
@@ -21,53 +23,108 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private SeasonalBackgroundLoader backgroundLoader { get; set; }
|
private SeasonalBackgroundLoader backgroundLoader { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
|
||||||
|
private WelcomeMusicManager musicManager { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
private DialogOverlay dialogOverlay { get; set; }
|
||||||
|
|
||||||
private IBindable<APIUser> user;
|
private IBindable<APIUser> user;
|
||||||
|
|
||||||
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
|
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
|
||||||
|
|
||||||
private Bindable<bool> useSeasonalBackgrounds;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, IAPIProvider api)
|
private void load(OsuConfigManager config, IAPIProvider api)
|
||||||
{
|
{
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
user = api.LocalUser.GetBoundCopy();
|
user = api.LocalUser.GetBoundCopy();
|
||||||
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
|
|
||||||
|
var backgroundModeBindable = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
||||||
|
var enabledProxyBindable = new Bindable<bool>();
|
||||||
|
backgroundModeBindable.BindValueChanged(mode => enabledProxyBindable.Value = mode.NewValue == SeasonalBackgroundMode.Always, true);
|
||||||
|
enabledProxyBindable.BindValueChanged(enabled => backgroundModeBindable.Value = enabled.NewValue ? SeasonalBackgroundMode.Always : SeasonalBackgroundMode.Never);
|
||||||
|
|
||||||
var backgroundToggle = new SettingsCheckbox
|
var backgroundToggle = new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = UserInterfaceStrings.UseSeasonalBackgrounds,
|
LabelText = UserInterfaceStrings.UseSeasonalBackgrounds,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2),
|
Current = enabledProxyBindable
|
||||||
ClassicDefault = true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var categoryDropdown = new SettingsDropdown<string>
|
var categoryDropdown = new SettingsDropdown<string>
|
||||||
{
|
{
|
||||||
LabelText = UserInterfaceStrings.SeasonalBackgroundsCategories,
|
LabelText = UserInterfaceStrings.SeasonalBackgroundsCategories,
|
||||||
Current = config.GetBindable<string>(OsuSetting.BackgroundCategory)
|
Current = config.GetBindable<string>(OsuSetting.BackgroundCategory)
|
||||||
};
|
};
|
||||||
|
|
||||||
var refreshButton = new SettingsButton
|
var refreshButton = new SettingsButton
|
||||||
{
|
{
|
||||||
Text = UserInterfaceStrings.SeasonalBackgroundsRefresh,
|
Text = UserInterfaceStrings.SeasonalBackgroundsRefresh,
|
||||||
Action = () => backgroundLoader.RefreshCategories()
|
Action = () => backgroundLoader.RefreshCategories()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: the category dropdown disappear if no backgrounds (e.g. when first enabling the setting)
|
|
||||||
refreshButton.CanBeShown.BindTo(useSeasonalBackgrounds);
|
|
||||||
categoryDropdown.CanBeShown.BindTo(useSeasonalBackgrounds);
|
|
||||||
useSeasonalBackgrounds.BindValueChanged(
|
|
||||||
_ => backgroundLoader.RefreshCategories(true)
|
|
||||||
);
|
|
||||||
|
|
||||||
backgroundLoader.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
|
backgroundLoader.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
|
||||||
|
backgroundModeBindable.BindValueChanged(mode =>
|
||||||
|
{
|
||||||
|
if (mode.NewValue == SeasonalBackgroundMode.Always)
|
||||||
|
{
|
||||||
|
categoryDropdown.Show();
|
||||||
|
refreshButton.Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
categoryDropdown.Hide();
|
||||||
|
refreshButton.Hide();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
var musicModeDropdown = new SettingsEnumDropdown<WelcomeMusicMode>
|
||||||
|
{
|
||||||
|
LabelText = "Музыкальное приветствие",
|
||||||
|
Current = config.GetBindable<WelcomeMusicMode>(OsuSetting.WelcomeMusicMode)
|
||||||
|
};
|
||||||
|
|
||||||
|
var musicCategoryDropdown = new SettingsDropdown<string>
|
||||||
|
{
|
||||||
|
LabelText = "Категория музыки",
|
||||||
|
Current = config.GetBindable<string>(OsuSetting.WelcomeMusicCategory)
|
||||||
|
};
|
||||||
|
|
||||||
|
var refreshMusicButton = new SettingsButton
|
||||||
|
{
|
||||||
|
Text = "Обновить категории музыки",
|
||||||
|
Action = () => musicManager.RefreshCategories()
|
||||||
|
};
|
||||||
|
|
||||||
|
musicModeDropdown.Current.BindValueChanged(mode =>
|
||||||
|
{
|
||||||
|
if (mode.NewValue == WelcomeMusicMode.Custom)
|
||||||
|
{
|
||||||
|
musicCategoryDropdown.Show();
|
||||||
|
refreshMusicButton.Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
musicCategoryDropdown.Hide();
|
||||||
|
refreshMusicButton.Hide();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
musicCategoryDropdown.Current.BindValueChanged(category =>
|
||||||
|
{
|
||||||
|
if (category.OldValue != null &&
|
||||||
|
musicModeDropdown.Current.Value == WelcomeMusicMode.Custom &&
|
||||||
|
!category.OldValue.Equals(category.NewValue))
|
||||||
|
{
|
||||||
|
dialogOverlay.Push(new ConfirmDialog("Для применения этой настройки требуется перезапуск.",
|
||||||
|
() => musicManager.RequestRestart()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
musicManager.AvailableCategories.BindValueChanged(categories => musicCategoryDropdown.Items = categories.NewValue, true);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = UserInterfaceStrings.ShowMenuTips,
|
LabelText = UserInterfaceStrings.ShowMenuTips,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.MenuTips),
|
Current = config.GetBindable<bool>(OsuSetting.MenuTips)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
@@ -81,6 +138,9 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
LabelText = UserInterfaceStrings.OsuMusicTheme,
|
LabelText = UserInterfaceStrings.OsuMusicTheme,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.MenuMusic)
|
Current = config.GetBindable<bool>(OsuSetting.MenuMusic)
|
||||||
},
|
},
|
||||||
|
musicModeDropdown,
|
||||||
|
musicCategoryDropdown,
|
||||||
|
refreshMusicButton,
|
||||||
new SettingsEnumDropdown<IntroSequence>
|
new SettingsEnumDropdown<IntroSequence>
|
||||||
{
|
{
|
||||||
LabelText = UserInterfaceStrings.IntroSequence,
|
LabelText = UserInterfaceStrings.IntroSequence,
|
||||||
@@ -94,12 +154,6 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
backgroundToggle,
|
backgroundToggle,
|
||||||
categoryDropdown,
|
categoryDropdown,
|
||||||
refreshButton,
|
refreshButton,
|
||||||
new SettingsColour
|
|
||||||
{
|
|
||||||
LabelText = @"osu! logo colour",
|
|
||||||
Current = config.GetBindable<Colour4>(OsuSetting.MenuCookieColor),
|
|
||||||
ClassicDefault = Colour4.FromHex(@"ff66ba"),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,6 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsCheckbox
|
|
||||||
{
|
|
||||||
LabelText = UserInterfaceStrings.ForceLegacySongSelect,
|
|
||||||
Current = config.GetBindable<bool>(OsuSetting.ForceLegacySongSelect),
|
|
||||||
ClassicDefault = false
|
|
||||||
},
|
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = UserInterfaceStrings.ShowConvertedBeatmaps,
|
LabelText = UserInterfaceStrings.ShowConvertedBeatmaps,
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Localisation.HUD;
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@@ -26,8 +24,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => "Fail if your accuracy drops too low!";
|
public override LocalisableString Description => "Fail if your accuracy drops too low!";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModAccuracyChallenge;
|
|
||||||
|
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@@ -29,8 +27,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => "Let track speed adapt to you.";
|
public override LocalisableString Description => "Let track speed adapt to you.";
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModAdaptiveSpeed;
|
|
||||||
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Autoplay";
|
public override string Name => "Autoplay";
|
||||||
public override string Acronym => "AT";
|
public override string Acronym => "AT";
|
||||||
public override IconUsage? Icon => OsuIcon.ModAutoplay;
|
public override IconUsage? Icon => OsuIcon.ModAuto;
|
||||||
public override ModType Type => ModType.Automation;
|
public override ModType Type => ModType.Automation;
|
||||||
public override LocalisableString Description => "Watch a perfect automated play through the song.";
|
public override LocalisableString Description => "Watch a perfect automated play through the song.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@@ -38,7 +36,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override string Name => "Barrel Roll";
|
public override string Name => "Barrel Roll";
|
||||||
public override string Acronym => "BR";
|
public override string Acronym => "BR";
|
||||||
public override IconUsage? Icon => OsuIcon.ModBarrelRoll;
|
|
||||||
public override LocalisableString Description => "The whole playfield is on a wheel!";
|
public override LocalisableString Description => "The whole playfield is on a wheel!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -15,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override double ScoreMultiplier => 0.96;
|
public override double ScoreMultiplier => 0.96;
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModClassic;
|
public override IconUsage? Icon => FontAwesome.Solid.History;
|
||||||
|
|
||||||
public override LocalisableString Description => "Feeling nostalgic?";
|
public override LocalisableString Description => "Feeling nostalgic?";
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
@@ -15,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Daycore";
|
public override string Name => "Daycore";
|
||||||
public override string Acronym => "DC";
|
public override string Acronym => "DC";
|
||||||
public override IconUsage? Icon => OsuIcon.ModDaycore;
|
public override IconUsage? Icon => null;
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
public override LocalisableString Description => "Whoaaaaa...";
|
public override LocalisableString Description => "Whoaaaaa...";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => UsesDefaultConfiguration;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using osu.Framework.Localisation;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -23,7 +22,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
|
|
||||||
public override IconUsage? Icon => OsuIcon.ModDifficultyAdjust;
|
public override IconUsage? Icon => FontAwesome.Solid.Hammer;
|
||||||
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@@ -13,8 +14,8 @@ using osu.Framework.Graphics.Rendering.Vertices;
|
|||||||
using osu.Framework.Graphics.Shaders;
|
using osu.Framework.Graphics.Shaders;
|
||||||
using osu.Framework.Graphics.Shaders.Types;
|
using osu.Framework.Graphics.Shaders.Types;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Layout;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.OpenGL.Vertices;
|
using osu.Game.Graphics.OpenGL.Vertices;
|
||||||
@@ -84,11 +85,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
flashlight.Colour = Color4.Black;
|
flashlight.Colour = Color4.Black;
|
||||||
|
|
||||||
flashlight.Combo.BindTo(Combo);
|
flashlight.Combo.BindTo(Combo);
|
||||||
|
flashlight.GetPlayfieldScale = () => drawableRuleset.PlayfieldAdjustmentContainer.Scale;
|
||||||
var playfieldDrawInfoTracker = new PlayfieldDrawInfoTracker();
|
|
||||||
|
|
||||||
drawableRuleset.PlayfieldAdjustmentContainer.Add(playfieldDrawInfoTracker);
|
|
||||||
flashlight.PlayfieldDrawInfoTracker = playfieldDrawInfoTracker;
|
|
||||||
|
|
||||||
drawableRuleset.Overlays.Add(new Container
|
drawableRuleset.Overlays.Add(new Container
|
||||||
{
|
{
|
||||||
@@ -114,9 +111,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override bool RemoveCompletedTransforms => false;
|
public override bool RemoveCompletedTransforms => false;
|
||||||
|
|
||||||
internal PlayfieldDrawInfoTracker PlayfieldDrawInfoTracker { get; set; } = null!;
|
internal Func<Vector2>? GetPlayfieldScale;
|
||||||
|
|
||||||
private DrawInfo playfieldDrawInfo => PlayfieldDrawInfoTracker.DrawInfo;
|
|
||||||
|
|
||||||
private readonly float defaultFlashlightSize;
|
private readonly float defaultFlashlightSize;
|
||||||
private readonly float sizeMultiplier;
|
private readonly float sizeMultiplier;
|
||||||
@@ -151,8 +146,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
isBreakTime.BindTo(player.IsBreakTime);
|
isBreakTime.BindTo(player.IsBreakTime);
|
||||||
isBreakTime.BindValueChanged(_ => UpdateFlashlightSize(GetSize()), true);
|
isBreakTime.BindValueChanged(_ => UpdateFlashlightSize(GetSize()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayfieldDrawInfoTracker.OnDrawInfoInvalidate += () => Invalidate(Invalidation.DrawNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void UpdateFlashlightSize(float size);
|
protected abstract void UpdateFlashlightSize(float size);
|
||||||
@@ -163,6 +156,15 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
float size = defaultFlashlightSize * sizeMultiplier;
|
float size = defaultFlashlightSize * sizeMultiplier;
|
||||||
|
|
||||||
|
if (GetPlayfieldScale != null)
|
||||||
|
{
|
||||||
|
Vector2 playfieldScale = GetPlayfieldScale();
|
||||||
|
|
||||||
|
Debug.Assert(Precision.AlmostEquals(Math.Abs(playfieldScale.X), Math.Abs(playfieldScale.Y)),
|
||||||
|
@"Playfield has non-proportional scaling. Flashlight implementations should be revisited with regard to balance.");
|
||||||
|
size *= Math.Abs(playfieldScale.X);
|
||||||
|
}
|
||||||
|
|
||||||
if (isBreakTime.Value)
|
if (isBreakTime.Value)
|
||||||
size *= 2.5f;
|
size *= 2.5f;
|
||||||
else if (comboBasedSize)
|
else if (comboBasedSize)
|
||||||
@@ -263,11 +265,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
shader = Source.shader;
|
shader = Source.shader;
|
||||||
screenSpaceDrawQuad = Source.ScreenSpaceDrawQuad;
|
screenSpaceDrawQuad = Source.ScreenSpaceDrawQuad;
|
||||||
flashlightPosition = Vector2Extensions.Transform(Source.FlashlightPosition, DrawInfo.Matrix);
|
flashlightPosition = Vector2Extensions.Transform(Source.FlashlightPosition, DrawInfo.Matrix);
|
||||||
|
flashlightSize = Source.FlashlightSize * DrawInfo.Matrix.ExtractScale().Xy;
|
||||||
// scale the flashlight based on the playfield to match gameplay components scale.
|
|
||||||
Vector2 drawInfoScale = Source.playfieldDrawInfo.Matrix.ExtractScale().Xy;
|
|
||||||
flashlightSize = Source.FlashlightSize * drawInfoScale;
|
|
||||||
|
|
||||||
flashlightDim = Source.FlashlightDim;
|
flashlightDim = Source.FlashlightDim;
|
||||||
flashlightSmoothness = Source.flashlightSmoothness;
|
flashlightSmoothness = Source.flashlightSmoothness;
|
||||||
}
|
}
|
||||||
@@ -323,33 +321,5 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The purpose of this component is to track any changes to <c>Playfield.Parent.DrawInfo</c>
|
|
||||||
/// (by being added to the content of <see cref="PlayfieldAdjustmentContainer"/>).
|
|
||||||
/// All in order for the flashlight to invalidate its draw node and read any changes in the playfield's scaling.
|
|
||||||
/// </summary>
|
|
||||||
internal partial class PlayfieldDrawInfoTracker : Component
|
|
||||||
{
|
|
||||||
private readonly LayoutValue drawInfoLayout = new LayoutValue(Invalidation.DrawInfo);
|
|
||||||
|
|
||||||
public Action? OnDrawInfoInvalidate;
|
|
||||||
|
|
||||||
public PlayfieldDrawInfoTracker()
|
|
||||||
{
|
|
||||||
AddLayout(drawInfoLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
if (!drawInfoLayout.IsValid)
|
|
||||||
{
|
|
||||||
OnDrawInfoInvalidate?.Invoke();
|
|
||||||
drawInfoLayout.Validate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Half Time";
|
public override string Name => "Half Time";
|
||||||
public override string Acronym => "HT";
|
public override string Acronym => "HT";
|
||||||
public override IconUsage? Icon => OsuIcon.ModHalfTime;
|
public override IconUsage? Icon => OsuIcon.ModHalftime;
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
public override LocalisableString Description => "Less zoom...";
|
public override LocalisableString Description => "Less zoom...";
|
||||||
public override bool Ranked => SpeedChange.IsDefault;
|
public override bool Ranked => SpeedChange.IsDefault;
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModMirror : Mod
|
public abstract class ModMirror : Mod
|
||||||
{
|
{
|
||||||
public override string Name => "Mirror";
|
public override string Name => "Mirror";
|
||||||
public override string Acronym => "MR";
|
public override string Acronym => "MR";
|
||||||
public override IconUsage? Icon => OsuIcon.ModMirror;
|
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Muted";
|
public override string Name => "Muted";
|
||||||
public override string Acronym => "MU";
|
public override string Acronym => "MU";
|
||||||
public override IconUsage? Icon => OsuIcon.ModMuted;
|
public override IconUsage? Icon => FontAwesome.Solid.VolumeMute;
|
||||||
public override LocalisableString Description => "Can you still feel the rhythm without music?";
|
public override LocalisableString Description => "Can you still feel the rhythm without music?";
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -16,7 +15,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Acronym => "NM";
|
public override string Acronym => "NM";
|
||||||
public override LocalisableString Description => "No mods applied.";
|
public override LocalisableString Description => "No mods applied.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override IconUsage? Icon => OsuIcon.ModNoMod;
|
public override IconUsage? Icon => FontAwesome.Solid.Ban;
|
||||||
public override ModType Type => ModType.System;
|
public override ModType Type => ModType.System;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "No Scope";
|
public override string Name => "No Scope";
|
||||||
public override string Acronym => "NS";
|
public override string Acronym => "NS";
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
public override IconUsage? Icon => OsuIcon.ModNoScope;
|
public override IconUsage? Icon => FontAwesome.Solid.EyeSlash;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "Random";
|
public override string Name => "Random";
|
||||||
public override string Acronym => "RD";
|
public override string Acronym => "RD";
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override IconUsage? Icon => OsuIcon.ModRandom;
|
public override IconUsage? Icon => OsuIcon.Dice;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -15,7 +13,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public override string Name => "Score V2";
|
public override string Name => "Score V2";
|
||||||
public override string Acronym => @"SV2";
|
public override string Acronym => @"SV2";
|
||||||
public override IconUsage? Icon => OsuIcon.ModScoreV2;
|
|
||||||
public override ModType Type => ModType.System;
|
public override ModType Type => ModType.System;
|
||||||
public override LocalisableString Description => "Score set on earlier osu! versions with the V2 scoring algorithm active.";
|
public override LocalisableString Description => "Score set on earlier osu! versions with the V2 scoring algorithm active.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// 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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -16,7 +14,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Acronym => "SY";
|
public override string Acronym => "SY";
|
||||||
public override LocalisableString Description => "Colours hit objects based on the rhythm.";
|
public override LocalisableString Description => "Colours hit objects based on the rhythm.";
|
||||||
public override double ScoreMultiplier => 0.8;
|
public override double ScoreMultiplier => 0.8;
|
||||||
public override IconUsage? Icon => OsuIcon.ModSynesthesia;
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
public sealed override string Name => "Touch Device";
|
public sealed override string Name => "Touch Device";
|
||||||
public sealed override string Acronym => "TD";
|
public sealed override string Acronym => "TD";
|
||||||
public sealed override IconUsage? Icon => OsuIcon.ModTouchDevice;
|
public sealed override IconUsage? Icon => OsuIcon.PlayStyleTouch;
|
||||||
public sealed override LocalisableString Description => "Automatically applied to plays on devices with a touchscreen.";
|
public sealed override LocalisableString Description => "Automatically applied to plays on devices with a touchscreen.";
|
||||||
public sealed override double ScoreMultiplier => 1;
|
public sealed override double ScoreMultiplier => 1;
|
||||||
public sealed override ModType Type => ModType.System;
|
public sealed override ModType Type => ModType.System;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -15,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "Wind Down";
|
public override string Name => "Wind Down";
|
||||||
public override string Acronym => "WD";
|
public override string Acronym => "WD";
|
||||||
public override LocalisableString Description => "Sloooow doooown...";
|
public override LocalisableString Description => "Sloooow doooown...";
|
||||||
public override IconUsage? Icon => OsuIcon.ModWindDown;
|
public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleDown;
|
||||||
|
|
||||||
public override BindableNumber<double> InitialRate { get; } = new BindableDouble(1)
|
public override BindableNumber<double> InitialRate { get; } = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@@ -15,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "Wind Up";
|
public override string Name => "Wind Up";
|
||||||
public override string Acronym => "WU";
|
public override string Acronym => "WU";
|
||||||
public override LocalisableString Description => "Can you keep up?";
|
public override LocalisableString Description => "Can you keep up?";
|
||||||
public override IconUsage? Icon => OsuIcon.ModWindUp;
|
public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleUp;
|
||||||
|
|
||||||
public override BindableNumber<double> InitialRate { get; } = new BindableDouble(1)
|
public override BindableNumber<double> InitialRate { get; } = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
public ReplayInputHandler? ReplayInputHandler { get; set; }
|
public ReplayInputHandler? ReplayInputHandler { get; set; }
|
||||||
|
|
||||||
private int invalidBassTimeLogCount;
|
private double? lastBackwardsSeekLogTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of CPU milliseconds to spend at most during seek catch-up.
|
/// The number of CPU milliseconds to spend at most during seek catch-up.
|
||||||
@@ -161,11 +161,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
//
|
//
|
||||||
// In testing this triggers *very* rarely even when set to super low values (10 ms). The cases we're worried about involve multi-second jumps.
|
// In testing this triggers *very* rarely even when set to super low values (10 ms). The cases we're worried about involve multi-second jumps.
|
||||||
// A difference of more than 500 ms seems like a sane number we should never exceed.
|
// A difference of more than 500 ms seems like a sane number we should never exceed.
|
||||||
if (!allowReferenceClockSeeks && Math.Abs(proposedTime - referenceClock.CurrentTime) > 1500)
|
if (!allowReferenceClockSeeks && Math.Abs(proposedTime - referenceClock.CurrentTime) > 500)
|
||||||
{
|
{
|
||||||
if (invalidBassTimeLogCount < 10)
|
if (lastBackwardsSeekLogTime == null || Math.Abs(Clock.CurrentTime - lastBackwardsSeekLogTime.Value) > 1000)
|
||||||
{
|
{
|
||||||
invalidBassTimeLogCount++;
|
lastBackwardsSeekLogTime = Clock.CurrentTime;
|
||||||
Logger.Log("Ignoring likely invalid time value provided by BASS during gameplay");
|
Logger.Log("Ignoring likely invalid time value provided by BASS during gameplay");
|
||||||
Logger.Log($"- provided: {referenceClock.CurrentTime:N2}");
|
Logger.Log($"- provided: {referenceClock.CurrentTime:N2}");
|
||||||
Logger.Log($"- expected: {proposedTime:N2}");
|
Logger.Log($"- expected: {proposedTime:N2}");
|
||||||
@@ -175,8 +175,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidBassTimeLogCount = 0;
|
|
||||||
|
|
||||||
// if the proposed time is the same as the current time, assume that the clock will continue progressing in the same direction as previously.
|
// if the proposed time is the same as the current time, assume that the clock will continue progressing in the same direction as previously.
|
||||||
// this avoids spurious flips in direction from -1 to 1 during rewinds.
|
// this avoids spurious flips in direction from -1 to 1 during rewinds.
|
||||||
if (state == PlaybackState.Valid && proposedTime != manualClock.CurrentTime)
|
if (state == PlaybackState.Valid && proposedTime != manualClock.CurrentTime)
|
||||||
|
|||||||
@@ -167,13 +167,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
Size = new Vector2(45),
|
||||||
// the mod icon assets in `osu-resources` are sized such that they are flush with the hexagonal background with no shadow baked in.
|
|
||||||
// the `Icons/BeatmapDetails/mod-icon` asset (of size 135x100) has a shadow and some extra transparent pixels baked in.
|
|
||||||
// the hexagonal background on that asset, excluding its shadow and the transparent pixels, is 131px wide and 92px high.
|
|
||||||
// height is divided by 135 rather than by 100, because this entire component is square-sized.
|
|
||||||
Width = 131 / 135f,
|
|
||||||
Height = 92 / 135f,
|
|
||||||
Icon = FontAwesome.Solid.Question
|
Icon = FontAwesome.Solid.Question
|
||||||
},
|
},
|
||||||
adjustmentMarker = new Container
|
adjustmentMarker = new Container
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
Spacing = new Vector2(0, 4),
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Child = tinySwitch = new ModSwitchTiny(mod)
|
Child = tinySwitch = new ModSwitchTiny(mod)
|
||||||
{
|
{
|
||||||
@@ -78,9 +79,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Size = new Vector2(37, 26),
|
Size = new Vector2(21),
|
||||||
// arbitrary adjustment for better vertical alignment
|
|
||||||
Margin = new MarginPadding { Top = -1 },
|
|
||||||
Icon = mod.Icon.Value
|
Icon = mod.Icon.Value
|
||||||
});
|
});
|
||||||
tinySwitch.Scale = new Vector2(0.3f);
|
tinySwitch.Scale = new Vector2(0.3f);
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ using osu.Game.Localisation;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Dialog;
|
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Overlays.OSD;
|
using osu.Game.Overlays.OSD;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@@ -1313,8 +1312,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
yield return upload;
|
yield return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return new EditorMenuItem("Remove all online IDs", MenuItemType.Destructive, anonymizeBeatmap);
|
|
||||||
|
|
||||||
if (editorBeatmap.BeatmapInfo.OnlineID > 0)
|
if (editorBeatmap.BeatmapInfo.OnlineID > 0)
|
||||||
{
|
{
|
||||||
yield return new OsuMenuItemSpacer();
|
yield return new OsuMenuItemSpacer();
|
||||||
@@ -1399,29 +1396,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
void startSubmission() => this.Push(new BeatmapSubmissionScreen());
|
void startSubmission() => this.Push(new BeatmapSubmissionScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void anonymizeBeatmap()
|
|
||||||
{
|
|
||||||
dialogOverlay.Push(new ConfirmDialog(
|
|
||||||
"Really remove online IDs?", () =>
|
|
||||||
{
|
|
||||||
var maps = editorBeatmap.BeatmapInfo.BeatmapSet.Beatmaps;
|
|
||||||
foreach (BeatmapInfo map in maps)
|
|
||||||
{
|
|
||||||
map.OnlineID = -1;
|
|
||||||
map.BeatmapSet.OnlineID = -1;
|
|
||||||
map.ResetOnlineInfo(true);
|
|
||||||
beatmapManager.Save(
|
|
||||||
map,
|
|
||||||
beatmapManager.GetWorkingBeatmap(map, true)!.Beatmap,
|
|
||||||
editorBeatmap.BeatmapSkin
|
|
||||||
); // as much as I don't want to mutate this much, there's no other choice
|
|
||||||
}
|
|
||||||
updateLastSavedHash();
|
|
||||||
onScreenDisplay?.Display(new BeatmapEditorToast("Online IDs removed", editorBeatmap.BeatmapInfo.GetDisplayTitle()));
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exportBeatmap(bool legacy)
|
private void exportBeatmap(bool legacy)
|
||||||
{
|
{
|
||||||
if (HasUnsavedChanges)
|
if (HasUnsavedChanges)
|
||||||
|
|||||||
@@ -3,13 +3,10 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Development;
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shaders;
|
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
@@ -18,11 +15,19 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Seasonal;
|
using osu.Game.Seasonal;
|
||||||
using IntroSequence = osu.Game.Configuration.IntroSequence;
|
using IntroSequence = osu.Game.Configuration.IntroSequence;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
|
||||||
namespace osu.Game.Screens
|
namespace osu.Game.Screens
|
||||||
{
|
{
|
||||||
public partial class Loader : StartupScreen
|
public partial class Loader : StartupScreen
|
||||||
{
|
{
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager config { get; set; }
|
||||||
|
[Resolved]
|
||||||
|
private WelcomeMusicManager musicManager { get; set; }
|
||||||
|
|
||||||
|
private WelcomeMusicMode musicMode;
|
||||||
|
|
||||||
public Loader()
|
public Loader()
|
||||||
{
|
{
|
||||||
ValidForResume = false;
|
ValidForResume = false;
|
||||||
@@ -30,17 +35,16 @@ namespace osu.Game.Screens
|
|||||||
|
|
||||||
private OsuScreen loadableScreen;
|
private OsuScreen loadableScreen;
|
||||||
private ShaderPrecompiler precompiler;
|
private ShaderPrecompiler precompiler;
|
||||||
|
|
||||||
private IntroSequence introSequence;
|
|
||||||
private LoadingSpinner spinner;
|
private LoadingSpinner spinner;
|
||||||
private ScheduledDelegate spinnerShow;
|
private ScheduledDelegate spinnerShow;
|
||||||
|
|
||||||
protected virtual OsuScreen CreateLoadableScreen() => getIntroSequence();
|
protected virtual OsuScreen CreateLoadableScreen()
|
||||||
|
|
||||||
private IntroScreen getIntroSequence()
|
|
||||||
{
|
{
|
||||||
// Headless tests run too fast to load non-circles intros correctly.
|
var introSequence = config.Get<IntroSequence>(OsuSetting.IntroSequence);
|
||||||
// They will hit the "audio can't play" notification and cause random test failures.
|
|
||||||
|
if (musicMode == WelcomeMusicMode.Custom)
|
||||||
|
return new IntroFade();
|
||||||
|
|
||||||
if (SeasonalUIConfig.ENABLED && !DebugUtils.IsNUnitRunning)
|
if (SeasonalUIConfig.ENABLED && !DebugUtils.IsNUnitRunning)
|
||||||
return new IntroChristmas(createMainMenu);
|
return new IntroChristmas(createMainMenu);
|
||||||
|
|
||||||
@@ -51,27 +55,28 @@ namespace osu.Game.Screens
|
|||||||
{
|
{
|
||||||
case IntroSequence.Circles:
|
case IntroSequence.Circles:
|
||||||
return new IntroCircles(createMainMenu);
|
return new IntroCircles(createMainMenu);
|
||||||
|
|
||||||
case IntroSequence.Welcome:
|
case IntroSequence.Welcome:
|
||||||
return new IntroWelcome(createMainMenu);
|
return new IntroWelcome(createMainMenu);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new IntroTriangles(createMainMenu);
|
return new IntroTriangles(createMainMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainMenu createMainMenu() => new MainMenu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MainMenu createMainMenu() => new MainMenu();
|
||||||
|
|
||||||
protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler();
|
protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler();
|
||||||
|
|
||||||
public override void OnEntering(ScreenTransitionEvent e)
|
public override async void OnEntering(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
base.OnEntering(e);
|
base.OnEntering(e);
|
||||||
|
|
||||||
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), AddInternal);
|
musicMode = config.Get<WelcomeMusicMode>(OsuSetting.WelcomeMusicMode);
|
||||||
|
|
||||||
|
await musicManager.PreloadCurrentTrack().ConfigureAwait(true);
|
||||||
|
|
||||||
LoadComponentAsync(loadableScreen = CreateLoadableScreen());
|
LoadComponentAsync(loadableScreen = CreateLoadableScreen());
|
||||||
|
|
||||||
|
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), AddInternal);
|
||||||
LoadComponentAsync(spinner = new LoadingSpinner(true, true)
|
LoadComponentAsync(spinner = new LoadingSpinner(true, true)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
@@ -88,7 +93,7 @@ namespace osu.Game.Screens
|
|||||||
|
|
||||||
private void checkIfLoaded()
|
private void checkIfLoaded()
|
||||||
{
|
{
|
||||||
if (loadableScreen?.LoadState != LoadState.Ready || !precompiler.FinishedCompiling)
|
if (loadableScreen?.LoadState != LoadState.Ready || !precompiler.IsLoaded)
|
||||||
{
|
{
|
||||||
Schedule(checkIfLoaded);
|
Schedule(checkIfLoaded);
|
||||||
return;
|
return;
|
||||||
@@ -105,55 +110,9 @@ namespace osu.Game.Screens
|
|||||||
this.Push(loadableScreen);
|
this.Push(loadableScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuConfigManager config)
|
|
||||||
{
|
|
||||||
introSequence = config.Get<IntroSequence>(OsuSetting.IntroSequence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compiles a set of shaders before continuing. Attempts to draw some frames between compilation by limiting to one compile per draw frame.
|
|
||||||
/// </summary>
|
|
||||||
public partial class ShaderPrecompiler : Drawable
|
public partial class ShaderPrecompiler : Drawable
|
||||||
{
|
{
|
||||||
private readonly List<IShader> loadTargets = new List<IShader>();
|
// ... код ShaderPrecompiler остается без изменений ... (Блять, а где он?)
|
||||||
|
|
||||||
public bool FinishedCompiling { get; private set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(ShaderManager manager)
|
|
||||||
{
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.BLUR));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
|
||||||
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"TriangleBorder"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"FastCircle"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"CircularProgress"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"ArgonBarPath"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"ArgonBarPathBackground"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"SaturationSelectorBackground"));
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"HueSelectorBackground"));
|
|
||||||
loadTargets.Add(manager.Load(@"LogoAnimation", @"LogoAnimation"));
|
|
||||||
|
|
||||||
// Ruleset local shader usage (should probably move somewhere else).
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, @"SpinnerGlow"));
|
|
||||||
loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool AllLoaded => loadTargets.All(s => s.IsLoaded);
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
// if our target is null we are done.
|
|
||||||
if (AllLoaded)
|
|
||||||
{
|
|
||||||
FinishedCompiling = true;
|
|
||||||
Expire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
30
osu.Game/Screens/Menu/IntroFade.cs
Normal file
30
osu.Game/Screens/Menu/IntroFade.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Menu
|
||||||
|
{
|
||||||
|
public partial class IntroFade : OsuScreen
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private WelcomeMusicManager? musicManager { get; set; }
|
||||||
|
|
||||||
|
public override void OnEntering(ScreenTransitionEvent e)
|
||||||
|
{
|
||||||
|
base.OnEntering(e);
|
||||||
|
|
||||||
|
this.FadeInFromZero(1000, Easing.OutQuint);
|
||||||
|
|
||||||
|
#pragma warning disable CS8602 // Разыменование вероятной пустой ссылки.
|
||||||
|
var track = musicManager.GetPreloadedTrack();
|
||||||
|
#pragma warning restore CS8602 // Разыменование вероятной пустой ссылки.
|
||||||
|
track?.Start();
|
||||||
|
|
||||||
|
Scheduler.AddDelayed(() => this.Push(new MainMenu()), 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,7 +39,6 @@ using osu.Game.Screens.Edit;
|
|||||||
using osu.Game.Screens.OnlinePlay.DailyChallenge;
|
using osu.Game.Screens.OnlinePlay.DailyChallenge;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||||
using osu.Game.Screens.Select;
|
|
||||||
using osu.Game.Screens.SelectV2;
|
using osu.Game.Screens.SelectV2;
|
||||||
using osu.Game.Seasonal;
|
using osu.Game.Seasonal;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@@ -106,7 +105,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
private ParallaxContainer buttonsContainer;
|
private ParallaxContainer buttonsContainer;
|
||||||
private SongTicker songTicker;
|
private SongTicker songTicker;
|
||||||
private Container logoTarget;
|
private Container logoTarget;
|
||||||
private OnlineMenuBanner onlineMenuBanner;
|
/*private OnlineMenuBanner onlineMenuBanner;*/
|
||||||
private MenuTipDisplay menuTipDisplay;
|
private MenuTipDisplay menuTipDisplay;
|
||||||
private FillFlowContainer bottomElementsFlow;
|
private FillFlowContainer bottomElementsFlow;
|
||||||
private SupporterDisplay supporterDisplay;
|
private SupporterDisplay supporterDisplay;
|
||||||
@@ -119,15 +118,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private IDisposable logoProxy;
|
private IDisposable logoProxy;
|
||||||
|
|
||||||
private Bindable<bool> forceSSV1;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics, AudioManager audio)
|
private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics, AudioManager audio)
|
||||||
{
|
{
|
||||||
holdDelay = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
holdDelay = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
||||||
loginDisplayed = statics.GetBindable<bool>(Static.LoginOverlayDisplayed);
|
loginDisplayed = statics.GetBindable<bool>(Static.LoginOverlayDisplayed);
|
||||||
showMobileDisclaimer = config.GetBindable<bool>(OsuSetting.ShowMobileDisclaimer);
|
showMobileDisclaimer = config.GetBindable<bool>(OsuSetting.ShowMobileDisclaimer);
|
||||||
forceSSV1 = config.GetBindable<bool>(OsuSetting.ForceLegacySongSelect);
|
|
||||||
|
|
||||||
if (host.CanExit)
|
if (host.CanExit)
|
||||||
{
|
{
|
||||||
@@ -202,12 +198,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
},
|
}
|
||||||
onlineMenuBanner = new OnlineMenuBanner
|
/*onlineMenuBanner = new OnlineMenuBanner
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
supporterDisplay = new SupporterDisplay
|
supporterDisplay = new SupporterDisplay
|
||||||
@@ -228,12 +224,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
case ButtonSystemState.Initial:
|
case ButtonSystemState.Initial:
|
||||||
case ButtonSystemState.Exit:
|
case ButtonSystemState.Exit:
|
||||||
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(baseDim), 500, Easing.OutSine));
|
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(baseDim), 500, Easing.OutSine));
|
||||||
onlineMenuBanner.State.Value = Visibility.Hidden;
|
/*onlineMenuBanner.State.Value = Visibility.Hidden;*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(baseDim * 0.8f), 500, Easing.OutSine));
|
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(baseDim * 0.8f), 500, Easing.OutSine));
|
||||||
onlineMenuBanner.State.Value = Visibility.Visible;
|
/*onlineMenuBanner.State.Value = Visibility.Visible;*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -483,7 +479,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSongSelect() => this.Push(forceSSV1.Value ? new PlaySongSelect() : new SoloSongSelect());
|
private void loadSongSelect() => this.Push(new SoloSongSelect());
|
||||||
|
|
||||||
private partial class MobileDisclaimerDialog : PopupDialog
|
private partial class MobileDisclaimerDialog : PopupDialog
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
@@ -21,7 +20,6 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Framework.Input.StateChanges;
|
using osu.Framework.Input.StateChanges;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
@@ -65,10 +63,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
protected Sample SampleDownbeat;
|
protected Sample SampleDownbeat;
|
||||||
|
|
||||||
private readonly Container colourAndTriangles;
|
private readonly Container colourAndTriangles;
|
||||||
private Box colourBox;
|
private readonly TrianglesV2 triangles;
|
||||||
private TrianglesV2 triangles;
|
|
||||||
|
|
||||||
private Bindable<Colour4> logoColour;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return value decides whether the logo should play its own sample for the click action.
|
/// Return value decides whether the logo should play its own sample for the click action.
|
||||||
@@ -191,13 +186,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
colourBox = new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = ColourInfo.GradientVertical(
|
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ff66ab"), Color4Extensions.FromHex(@"cc5289")),
|
||||||
Color4Extensions.FromHex(@"ff66ba"), // original osu! cookie pink
|
|
||||||
Color4Extensions.Darken(Color4Extensions.FromHex(@"ff66ba"), 0.5f)
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
triangles = new TrianglesV2
|
triangles = new TrianglesV2
|
||||||
{
|
{
|
||||||
@@ -206,10 +198,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
Thickness = 0.009f,
|
Thickness = 0.009f,
|
||||||
ScaleAdjust = 3,
|
ScaleAdjust = 3,
|
||||||
SpawnRatio = 1.4f,
|
SpawnRatio = 1.4f,
|
||||||
Colour = ColourInfo.GradientVertical(
|
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ff66ab"), Color4Extensions.FromHex(@"b6346f")),
|
||||||
Color4Extensions.FromHex(@"ff66ba"),
|
|
||||||
Color4Extensions.Darken(Color4Extensions.FromHex(@"ff66ba"), 1.0f)
|
|
||||||
),
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -260,22 +249,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateColour()
|
|
||||||
{
|
|
||||||
if (triangles == null || colourBox == null)
|
|
||||||
return; // we're still loading
|
|
||||||
|
|
||||||
colourBox.Colour = ColourInfo.GradientVertical(
|
|
||||||
logoColour.Value,
|
|
||||||
Color4Extensions.Darken(logoColour.Value, 0.5f)
|
|
||||||
);
|
|
||||||
|
|
||||||
triangles.Colour = ColourInfo.GradientVertical(
|
|
||||||
logoColour.Value,
|
|
||||||
Color4Extensions.Darken(logoColour.Value, 1.0f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Container LogoElements { get; private set; }
|
public Container LogoElements { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -303,7 +276,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures, AudioManager audio, OsuConfigManager config)
|
private void load(TextureStore textures, AudioManager audio)
|
||||||
{
|
{
|
||||||
sampleClick = audio.Samples.Get(@"Menu/osu-logo-select");
|
sampleClick = audio.Samples.Get(@"Menu/osu-logo-select");
|
||||||
|
|
||||||
@@ -312,10 +285,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
logo.Texture = textures.Get(@"Menu/logo");
|
logo.Texture = textures.Get(@"Menu/logo");
|
||||||
ripple.Texture = textures.Get(@"Menu/logo");
|
ripple.Texture = textures.Get(@"Menu/logo");
|
||||||
|
|
||||||
logoColour = config.GetBindable<Colour4>(OsuSetting.MenuCookieColor);
|
|
||||||
logoColour.BindValueChanged(_ => UpdateColour());
|
|
||||||
UpdateColour();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int lastBeatIndex;
|
private int lastBeatIndex;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
// Extra lenience is applied so the scores don't get cut off from the left due to elastic easing transforms.
|
// Extra lenience is applied so the scores don't get cut off from the left due to elastic easing transforms.
|
||||||
float xOffset = DrawableGameplayLeaderboardScore.SHEAR_WIDTH + DrawableGameplayLeaderboardScore.ELASTIC_WIDTH_LENIENCE;
|
float xOffset = DrawableGameplayLeaderboardScore.SHEAR_WIDTH + DrawableGameplayLeaderboardScore.ELASTIC_WIDTH_LENIENCE;
|
||||||
|
|
||||||
Width = 260 + xOffset;
|
Width = DrawableGameplayLeaderboardScore.EXTENDED_WIDTH + xOffset;
|
||||||
Height = 300;
|
Height = 300;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
@@ -155,10 +155,6 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// limit leaderboard dimensions to a sane minimum.
|
|
||||||
Width = Math.Max(Width, Flow.X + DrawableGameplayLeaderboardScore.MIN_WIDTH);
|
|
||||||
Height = Math.Max(Height, DrawableGameplayLeaderboardScore.PANEL_HEIGHT);
|
|
||||||
|
|
||||||
requiresScroll = Flow.DrawHeight > Height;
|
requiresScroll = Flow.DrawHeight > Height;
|
||||||
|
|
||||||
if (requiresScroll && TrackedScore != null)
|
if (requiresScroll && TrackedScore != null)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Layout;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@@ -27,15 +26,13 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
public partial class DrawableGameplayLeaderboardScore : CompositeDrawable
|
public partial class DrawableGameplayLeaderboardScore : CompositeDrawable
|
||||||
{
|
{
|
||||||
public const float MIN_WIDTH = extended_left_panel_width + avatar_size / 2 + 5;
|
public const float EXTENDED_WIDTH = extended_left_panel_width + right_panel_width;
|
||||||
|
|
||||||
private const float left_panel_extension_width = 20;
|
private const float left_panel_extension_width = 20;
|
||||||
|
|
||||||
private const float regular_left_panel_width = avatar_size + avatar_size / 2;
|
private const float regular_left_panel_width = avatar_size + avatar_size / 2;
|
||||||
private const float extended_left_panel_width = regular_left_panel_width + left_panel_extension_width;
|
private const float extended_left_panel_width = regular_left_panel_width + left_panel_extension_width;
|
||||||
|
private const float right_panel_width = 180;
|
||||||
private const float accuracy_combo_width_cutoff = 150;
|
|
||||||
private const float username_score_width_cutoff = 50;
|
|
||||||
|
|
||||||
private const float avatar_size = PANEL_HEIGHT;
|
private const float avatar_size = PANEL_HEIGHT;
|
||||||
|
|
||||||
@@ -101,8 +98,6 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; } = null!;
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
private readonly LayoutValue drawSizeLayout = new LayoutValue(Invalidation.DrawSize);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="DrawableGameplayLeaderboardScore"/>.
|
/// Creates a new <see cref="DrawableGameplayLeaderboardScore"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -121,12 +116,10 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
if (score.TeamColour != null)
|
if (score.TeamColour != null)
|
||||||
BackgroundColour = score.TeamColour.Value;
|
BackgroundColour = score.TeamColour.Value;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
AutoSizeAxes = Axes.X;
|
||||||
Height = PANEL_HEIGHT;
|
Height = PANEL_HEIGHT;
|
||||||
|
|
||||||
Shear = OsuGame.SHEAR;
|
Shear = OsuGame.SHEAR;
|
||||||
|
|
||||||
AddLayout(drawSizeLayout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@@ -205,6 +198,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
},
|
},
|
||||||
rightLayer = new Container
|
rightLayer = new Container
|
||||||
{
|
{
|
||||||
|
Width = right_panel_width,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
// negative left margin to make the X position of the right layer directly at the avatar center (rendered behind it).
|
// negative left margin to make the X position of the right layer directly at the avatar center (rendered behind it).
|
||||||
Margin = new MarginPadding { Left = -avatar_size / 2 },
|
Margin = new MarginPadding { Left = -avatar_size / 2 },
|
||||||
@@ -216,7 +210,8 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
},
|
},
|
||||||
scoreComponents = new Container
|
scoreComponents = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Width = right_panel_width,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
Padding = new MarginPadding { Left = avatar_size / 2 + 4, Right = 20, Vertical = 5 },
|
Padding = new MarginPadding { Left = avatar_size / 2 + 4, Right = 20, Vertical = 5 },
|
||||||
Shear = -OsuGame.SHEAR,
|
Shear = -OsuGame.SHEAR,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@@ -228,6 +223,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
ColumnDimensions = new[]
|
ColumnDimensions = new[]
|
||||||
{
|
{
|
||||||
new Dimension(),
|
new Dimension(),
|
||||||
|
new Dimension(GridSizeMode.Absolute, 10),
|
||||||
new Dimension(GridSizeMode.AutoSize),
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
},
|
},
|
||||||
RowDimensions = new[]
|
RowDimensions = new[]
|
||||||
@@ -246,6 +242,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold),
|
Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold),
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
},
|
},
|
||||||
|
Empty(),
|
||||||
accuracyText = new OsuSpriteText
|
accuracyText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
@@ -255,40 +252,27 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new GridContainer
|
new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
ColumnDimensions = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
new Dimension(),
|
scoreText = new OsuSpriteText
|
||||||
new Dimension(GridSizeMode.AutoSize),
|
|
||||||
},
|
|
||||||
RowDimensions = new[]
|
|
||||||
{
|
|
||||||
new Dimension(GridSizeMode.AutoSize),
|
|
||||||
},
|
|
||||||
Content = new[]
|
|
||||||
{
|
|
||||||
new[]
|
|
||||||
{
|
{
|
||||||
scoreText = new TruncatingSpriteText
|
Anchor = Anchor.BottomLeft,
|
||||||
{
|
Origin = Anchor.BottomLeft,
|
||||||
Anchor = Anchor.BottomLeft,
|
Font = OsuFont.Style.Body.With(weight: FontWeight.Regular),
|
||||||
Origin = Anchor.BottomLeft,
|
},
|
||||||
Font = OsuFont.Style.Body.With(weight: FontWeight.Regular),
|
comboText = new OsuSpriteText
|
||||||
RelativeSizeAxes = Axes.X,
|
{
|
||||||
},
|
Anchor = Anchor.BottomRight,
|
||||||
comboText = new OsuSpriteText
|
Origin = Anchor.BottomRight,
|
||||||
{
|
Font = OsuFont.Style.Caption2.With(weight: FontWeight.SemiBold),
|
||||||
Anchor = Anchor.BottomRight,
|
},
|
||||||
Origin = Anchor.BottomRight,
|
}
|
||||||
Font = OsuFont.Style.Caption2.With(weight: FontWeight.SemiBold),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -327,7 +311,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
if (expanded.NewValue)
|
if (expanded.NewValue)
|
||||||
{
|
{
|
||||||
rightLayer.ResizeWidthTo(computeRightLayerWidth(), panel_transition_duration, Easing.OutQuint);
|
rightLayer.ResizeWidthTo(right_panel_width, panel_transition_duration, Easing.OutQuint);
|
||||||
scoreComponents.FadeIn(panel_transition_duration, Easing.OutQuint);
|
scoreComponents.FadeIn(panel_transition_duration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -387,34 +371,6 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
scorePanel.BorderColour = ColourInfo.GradientVertical(colours.Blue1.Opacity(0.2f), colours.Blue1);
|
scorePanel.BorderColour = ColourInfo.GradientVertical(colours.Blue1.Opacity(0.2f), colours.Blue1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
if (!drawSizeLayout.IsValid)
|
|
||||||
{
|
|
||||||
if (Expanded.Value)
|
|
||||||
{
|
|
||||||
rightLayer.ClearTransforms(targetMember: nameof(Width));
|
|
||||||
rightLayer.Width = computeRightLayerWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
drawSizeLayout.Validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool showAccuracyAndCombo = rightLayer.Width >= accuracy_combo_width_cutoff;
|
|
||||||
|
|
||||||
accuracyText.Alpha = showAccuracyAndCombo ? 1 : 0;
|
|
||||||
comboText.Alpha = showAccuracyAndCombo ? 1 : 0;
|
|
||||||
|
|
||||||
bool showUsernameAndScore = rightLayer.Width >= username_score_width_cutoff;
|
|
||||||
|
|
||||||
usernameText.Alpha = showUsernameAndScore ? 1 : 0;
|
|
||||||
scoreText.Alpha = showUsernameAndScore ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float computeRightLayerWidth() => Math.Max(0, DrawWidth - extended_left_panel_width - avatar_size / 2);
|
|
||||||
|
|
||||||
private partial class ScoreAvatar : CompositeDrawable
|
private partial class ScoreAvatar : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly IUser? user;
|
private readonly IUser? user;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -29,19 +31,17 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private readonly Func<IBeatmap, IReadOnlyList<Mod>, Score> createScore;
|
private readonly Func<IBeatmap, IReadOnlyList<Mod>, Score> createScore;
|
||||||
|
|
||||||
|
private PlaybackSettings playbackSettings;
|
||||||
|
|
||||||
[Cached(typeof(IGameplayLeaderboardProvider))]
|
[Cached(typeof(IGameplayLeaderboardProvider))]
|
||||||
private readonly SoloGameplayLeaderboardProvider leaderboardProvider = new SoloGameplayLeaderboardProvider();
|
private readonly SoloGameplayLeaderboardProvider leaderboardProvider = new SoloGameplayLeaderboardProvider();
|
||||||
|
|
||||||
protected override UserActivity? InitialActivity =>
|
protected override UserActivity InitialActivity => new UserActivity.WatchingReplay(Score.ScoreInfo);
|
||||||
// score may be null if LoadedBeatmapSuccessfully is false.
|
|
||||||
Score == null ? null : new UserActivity.WatchingReplay(Score.ScoreInfo);
|
|
||||||
|
|
||||||
private bool isAutoplayPlayback => GameplayState.Mods.OfType<ModAutoplay>().Any();
|
private bool isAutoplayPlayback => GameplayState.Mods.OfType<ModAutoplay>().Any();
|
||||||
|
|
||||||
private double? lastFrameTime;
|
private double? lastFrameTime;
|
||||||
|
private ReplayFailIndicator failIndicator;
|
||||||
private ReplayFailIndicator? failIndicator;
|
|
||||||
private PlaybackSettings? playbackSettings;
|
|
||||||
|
|
||||||
protected override bool CheckModsAllowFailure()
|
protected override bool CheckModsAllowFailure()
|
||||||
{
|
{
|
||||||
@@ -60,12 +60,12 @@ namespace osu.Game.Screens.Play
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplayPlayer(Score score, PlayerConfiguration? configuration = null)
|
public ReplayPlayer(Score score, PlayerConfiguration configuration = null)
|
||||||
: this((_, _) => score, configuration)
|
: this((_, _) => score, configuration)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplayPlayer(Func<IBeatmap, IReadOnlyList<Mod>, Score> createScore, PlayerConfiguration? configuration = null)
|
public ReplayPlayer(Func<IBeatmap, IReadOnlyList<Mod>, Score> createScore, PlayerConfiguration configuration = null)
|
||||||
: base(configuration)
|
: base(configuration)
|
||||||
{
|
{
|
||||||
this.createScore = createScore;
|
this.createScore = createScore;
|
||||||
@@ -133,9 +133,6 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||||
{
|
{
|
||||||
if (!LoadedBeatmapSuccessfully)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
case GlobalAction.StepReplayBackward:
|
case GlobalAction.StepReplayBackward:
|
||||||
@@ -147,11 +144,11 @@ namespace osu.Game.Screens.Play
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.SeekReplayBackward:
|
case GlobalAction.SeekReplayBackward:
|
||||||
SeekInDirection(-5 * (float)playbackSettings!.UserPlaybackRate.Value);
|
SeekInDirection(-5 * (float)playbackSettings.UserPlaybackRate.Value);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.SeekReplayForward:
|
case GlobalAction.SeekReplayForward:
|
||||||
SeekInDirection(5 * (float)playbackSettings!.UserPlaybackRate.Value);
|
SeekInDirection(5 * (float)playbackSettings.UserPlaybackRate.Value);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.TogglePauseReplay:
|
case GlobalAction.TogglePauseReplay:
|
||||||
@@ -195,7 +192,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
// base logic intentionally suppressed - we have our own custom fail interaction
|
// base logic intentionally suppressed - we have our own custom fail interaction
|
||||||
ScoreProcessor.FailScore(Score.ScoreInfo);
|
ScoreProcessor.FailScore(Score.ScoreInfo);
|
||||||
failIndicator!.Display();
|
failIndicator.Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSuspending(ScreenTransitionEvent e)
|
public override void OnSuspending(ScreenTransitionEvent e)
|
||||||
@@ -207,18 +204,18 @@ namespace osu.Game.Screens.Play
|
|||||||
public override bool OnExiting(ScreenExitEvent e)
|
public override bool OnExiting(ScreenExitEvent e)
|
||||||
{
|
{
|
||||||
// safety against filters or samples from the indicator playing long after the screen is exited
|
// safety against filters or samples from the indicator playing long after the screen is exited
|
||||||
failIndicator?.RemoveAndDisposeImmediately();
|
failIndicator.RemoveAndDisposeImmediately();
|
||||||
return base.OnExiting(e);
|
return base.OnExiting(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopAllAudioEffects()
|
private void stopAllAudioEffects()
|
||||||
{
|
{
|
||||||
// safety against filters or samples from the indicator playing long after the screen is exited
|
// safety against filters or samples from the indicator playing long after the screen is exited
|
||||||
failIndicator?.RemoveAndDisposeImmediately();
|
failIndicator.RemoveAndDisposeImmediately();
|
||||||
|
|
||||||
if (GameplayClockContainer is MasterGameplayClockContainer master)
|
if (GameplayClockContainer is MasterGameplayClockContainer master)
|
||||||
{
|
{
|
||||||
playbackSettings?.UserPlaybackRate.UnbindFrom(master.UserPlaybackRate);
|
playbackSettings.UserPlaybackRate.UnbindFrom(master.UserPlaybackRate);
|
||||||
master.UserPlaybackRate.SetDefault();
|
master.UserPlaybackRate.SetDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
var scoresToShow = new List<GameplayLeaderboardScore>();
|
var scoresToShow = new List<GameplayLeaderboardScore>();
|
||||||
|
|
||||||
var scoresRequest = new IndexPlaylistScoresRequest(room.RoomID!.Value, playlistItem.ID);
|
var scoresRequest = new IndexPlaylistScoresRequest(room.RoomID!.Value, playlistItem.ID);
|
||||||
api.Perform(scoresRequest);
|
scoresRequest.Success += response =>
|
||||||
|
|
||||||
var response = scoresRequest.Response;
|
|
||||||
|
|
||||||
if (response != null)
|
|
||||||
{
|
{
|
||||||
isPartial = response.Scores.Count < response.TotalScores;
|
isPartial = response.Scores.Count < response.TotalScores;
|
||||||
|
|
||||||
@@ -54,7 +50,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
if (response.UserScore != null && response.Scores.All(s => s.ID != response.UserScore.ID))
|
if (response.UserScore != null && response.Scores.All(s => s.ID != response.UserScore.ID))
|
||||||
scoresToShow.Add(new GameplayLeaderboardScore(response.UserScore, tracked: false, GameplayLeaderboardScore.ComboDisplayMode.Highest));
|
scoresToShow.Add(new GameplayLeaderboardScore(response.UserScore, tracked: false, GameplayLeaderboardScore.ComboDisplayMode.Highest));
|
||||||
}
|
};
|
||||||
|
api.Perform(scoresRequest);
|
||||||
|
|
||||||
if (gameplayState != null)
|
if (gameplayState != null)
|
||||||
{
|
{
|
||||||
@@ -65,12 +62,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
// touching the public bindable must happen on the update thread for general thread safety,
|
// touching the public bindable must happen on the update thread for general thread safety,
|
||||||
// since we may have external subscribers bound already
|
// since we may have external subscribers bound already
|
||||||
Schedule(() =>
|
Schedule(() => scores.AddRange(scoresToShow));
|
||||||
{
|
Scheduler.AddDelayed(sort, 1000, true);
|
||||||
scores.AddRange(scoresToShow);
|
|
||||||
sort();
|
|
||||||
Scheduler.AddDelayed(sort, 1000, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// logic shared with SoloGameplayLeaderboardProvider
|
// logic shared with SoloGameplayLeaderboardProvider
|
||||||
|
|||||||
@@ -1,166 +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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.UserInterface;
|
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Framework.Screens;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Localisation;
|
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Overlays.Notifications;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Screens.Ranking;
|
|
||||||
using osu.Game.Users;
|
|
||||||
using osu.Game.Utils;
|
|
||||||
using osuTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
|
||||||
{
|
|
||||||
public partial class PlaySongSelect : SongSelect
|
|
||||||
{
|
|
||||||
private OsuScreen? playerLoader;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private INotificationOverlay? notifications { get; set; }
|
|
||||||
|
|
||||||
public override bool AllowExternalScreenChange => true;
|
|
||||||
|
|
||||||
public override MenuItem[] CreateForwardNavigationMenuItemsForBeatmap(Func<BeatmapInfo> getBeatmap) => new MenuItem[]
|
|
||||||
{
|
|
||||||
new OsuMenuItem(ButtonSystemStrings.Play.ToSentence(), MenuItemType.Highlighted, () => FinaliseSelection(getBeatmap())),
|
|
||||||
new OsuMenuItem(ButtonSystemStrings.Edit.ToSentence(), MenuItemType.Standard, () => Edit(getBeatmap()))
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override UserActivity InitialActivity => new UserActivity.ChoosingBeatmap();
|
|
||||||
|
|
||||||
private PlayBeatmapDetailArea playBeatmapDetailArea = null!;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
BeatmapOptions.AddButton(ButtonSystemStrings.Edit.ToSentence(), @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit());
|
|
||||||
|
|
||||||
AddInternal(new SongSelectTouchInputDetector());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void PresentScore(ScoreInfo score) =>
|
|
||||||
FinaliseSelection(score.BeatmapInfo, score.Ruleset, () => this.Push(new SoloResultsScreen(score)));
|
|
||||||
|
|
||||||
protected override BeatmapDetailArea CreateBeatmapDetailArea()
|
|
||||||
{
|
|
||||||
playBeatmapDetailArea = new PlayBeatmapDetailArea
|
|
||||||
{
|
|
||||||
Leaderboard =
|
|
||||||
{
|
|
||||||
ScoreSelected = PresentScore
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return playBeatmapDetailArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
|
||||||
{
|
|
||||||
switch (e.Key)
|
|
||||||
{
|
|
||||||
case Key.Enter:
|
|
||||||
case Key.KeypadEnter:
|
|
||||||
// this is a special hard-coded case; we can't rely on OnPressed (of SongSelect) as GlobalActionContainer is
|
|
||||||
// matching with exact modifier consideration (so Ctrl+Enter would be ignored).
|
|
||||||
FinaliseSelection();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IReadOnlyList<Mod>? modsAtGameplayStart;
|
|
||||||
|
|
||||||
private ModAutoplay? getAutoplayMod() => Ruleset.Value.CreateInstance().GetAutoplayMod();
|
|
||||||
|
|
||||||
protected override bool OnStart()
|
|
||||||
{
|
|
||||||
if (playerLoader != null) return false;
|
|
||||||
|
|
||||||
modsAtGameplayStart = Mods.Value.Select(m => m.DeepClone()).ToArray();
|
|
||||||
|
|
||||||
// Ctrl+Enter should start map with autoplay enabled.
|
|
||||||
if (GetContainingInputManager()?.CurrentState?.Keyboard.ControlPressed == true)
|
|
||||||
{
|
|
||||||
var autoInstance = getAutoplayMod();
|
|
||||||
|
|
||||||
if (autoInstance == null)
|
|
||||||
{
|
|
||||||
notifications?.Post(new SimpleNotification
|
|
||||||
{
|
|
||||||
Text = NotificationsStrings.NoAutoplayMod
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mods = Mods.Value.Append(autoInstance).ToArray();
|
|
||||||
|
|
||||||
if (!ModUtils.CheckCompatibleSet(mods, out var invalid))
|
|
||||||
mods = mods.Except(invalid).Append(autoInstance).ToArray();
|
|
||||||
|
|
||||||
Mods.Value = mods;
|
|
||||||
}
|
|
||||||
|
|
||||||
SampleConfirm?.Play();
|
|
||||||
|
|
||||||
this.Push(playerLoader = new PlayerLoader(createPlayer));
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Player createPlayer()
|
|
||||||
{
|
|
||||||
Player player;
|
|
||||||
|
|
||||||
var replayGeneratingMod = Mods.Value.OfType<ICreateReplayData>().FirstOrDefault();
|
|
||||||
|
|
||||||
if (replayGeneratingMod != null)
|
|
||||||
{
|
|
||||||
player = new ReplayPlayer((beatmap, mods) => replayGeneratingMod.CreateScoreFromReplayData(beatmap, mods));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player = new SoloPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnResuming(ScreenTransitionEvent e)
|
|
||||||
{
|
|
||||||
base.OnResuming(e);
|
|
||||||
revertMods();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnExiting(ScreenExitEvent e)
|
|
||||||
{
|
|
||||||
if (base.OnExiting(e))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
revertMods();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void revertMods()
|
|
||||||
{
|
|
||||||
if (playerLoader == null) return;
|
|
||||||
|
|
||||||
Mods.Value = modsAtGameplayStart;
|
|
||||||
playerLoader = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user