Compare commits
71 Commits
e3a7ae30cd
...
testing
| Author | SHA1 | Date | |
|---|---|---|---|
| de58aec23e | |||
|
|
734c6f933d | ||
|
|
ac213c90cb | ||
|
|
74ca87c252 | ||
|
|
032912e62b | ||
|
|
1e79c56240 | ||
| 86f0159e65 | |||
| ae5a64ba81 | |||
|
|
82256ae2de | ||
|
|
1142be45ec | ||
|
|
dcb6d71287 | ||
|
|
881a35b382 | ||
|
|
89d8b402af | ||
|
|
1d351002df | ||
|
|
2606f3a0b5 | ||
|
|
1c463aa060 | ||
|
|
7853abe8aa | ||
|
|
1aff418981 | ||
|
|
62e92bb242 | ||
|
|
79151ae5b4 | ||
|
|
c17db2cdd0 | ||
|
|
bbdd70c843 | ||
|
|
4250a54245 | ||
|
|
40fdb8662e | ||
|
|
6ce8b0a4bc | ||
|
|
b30047def6 | ||
|
|
0ffb86262f | ||
|
|
f71eb4b980 | ||
|
|
1faf02e860 | ||
|
|
d700375e55 | ||
|
|
095a67c24e | ||
|
|
86054497d0 | ||
|
|
c4f7dee82b | ||
|
|
22825f6509 | ||
|
|
691e8bcd05 | ||
|
|
e68bab4f4b | ||
|
|
9430a62af4 | ||
|
|
bdac75e542 | ||
|
|
5c2df50714 | ||
|
|
887d280bfa | ||
|
|
84db289779 | ||
|
|
4c0522b795 | ||
|
|
07ea9fe2a4 | ||
|
|
f73307876e | ||
|
|
4e4aa44a02 | ||
|
|
a6c001244f | ||
|
|
107098314a | ||
|
|
d1d76a76ba | ||
|
|
2a7e71d7fd | ||
|
|
0b4f96efc8 | ||
|
|
78c6973298 | ||
|
|
d8d7c80832 | ||
|
|
ae33690632 | ||
|
|
9e2ea63e70 | ||
|
|
79bfe7880a | ||
|
|
80fbcd5fbd | ||
|
|
9c2319b989 | ||
|
|
a040143825 | ||
|
|
1867aad1a6 | ||
|
|
b1bc5cae87 | ||
|
|
038bf3fdda | ||
|
|
61c3aad537 | ||
|
|
3aad0868af | ||
|
|
973c4c8319 | ||
|
|
ac21f8b960 | ||
|
|
0b3b6468a5 | ||
|
|
7d1c54f045 | ||
|
|
fd504e5641 | ||
|
|
93ed0483b6 | ||
|
|
4dd0672aa5 | ||
|
|
66eff14d2b |
@@ -21,7 +21,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ppy.localisationanalyser.tools": {
|
"ppy.localisationanalyser.tools": {
|
||||||
"version": "2024.802.0",
|
"version": "2025.1208.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"localisation"
|
"localisation"
|
||||||
]
|
]
|
||||||
|
|||||||
2
.github/workflows/ci.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
|||||||
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
||||||
|
|
||||||
- name: Dotnet code style
|
- name: Dotnet code style
|
||||||
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
|
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||||
|
|
||||||
- name: CodeFileSanity
|
- name: CodeFileSanity
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
4
.github/workflows/sentry-release.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
|||||||
uses: getsentry/action-release@v1
|
uses: getsentry/action-release@v1
|
||||||
env:
|
env:
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
SENTRY_ORG: ppy
|
SENTRY_ORG: jvnkosu
|
||||||
SENTRY_PROJECT: osu
|
SENTRY_PROJECT: client
|
||||||
SENTRY_URL: https://satellite.jvnko.boats/
|
SENTRY_URL: https://satellite.jvnko.boats/
|
||||||
with:
|
with:
|
||||||
environment: production
|
environment: production
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageType>Template</PackageType>
|
<PackageType>Template</PackageType>
|
||||||
<PackageId>ppy.osu.Game.Templates</PackageId>
|
<PackageId>jvnkosu.Client.Templates</PackageId>
|
||||||
<Title>osu! templates</Title>
|
<Title>osu! templates</Title>
|
||||||
<Authors>ppy Pty Ltd</Authors>
|
<Authors>ppy Pty Ltd</Authors>
|
||||||
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
|
|||||||
|
|
||||||
private static readonly UriAssociation[] uri_associations =
|
private static readonly UriAssociation[] uri_associations =
|
||||||
{
|
{
|
||||||
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
||||||
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
|||||||
leaderboard.Origin = Anchor.CentreLeft;
|
leaderboard.Origin = Anchor.CentreLeft;
|
||||||
leaderboard.X = 10;
|
leaderboard.X = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
|
|
||||||
if (spectatorList != null)
|
if (spectatorList != null)
|
||||||
spectatorList.Position = new Vector2(36, -66);
|
spectatorList.Position = new Vector2(36, -66);
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
new DrawableGameplayLeaderboard(),
|
new DrawableGameplayLeaderboard(),
|
||||||
|
|||||||
@@ -122,6 +122,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
|||||||
leaderboard.Origin = Anchor.CentreLeft;
|
leaderboard.Origin = Anchor.CentreLeft;
|
||||||
leaderboard.X = 10;
|
leaderboard.X = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
new LegacyManiaComboCounter(),
|
new LegacyManiaComboCounter(),
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
|
{
|
||||||
|
public partial class TestSceneGameplayCursorSizeChange : PlayerTestScene
|
||||||
|
{
|
||||||
|
private const float initial_cursor_size = 1f;
|
||||||
|
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private SkinManager? skins { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
if (skins != null) skins.CurrentSkinInfo.Value = skins.DefaultClassicSkin.SkinInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
AddStep("Set gameplay cursor size: 1", () => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, initial_cursor_size));
|
||||||
|
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
||||||
|
AddUntilStep("clock running", () => Player.GameplayClockContainer.IsRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPausedChangeCursorSize()
|
||||||
|
{
|
||||||
|
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
|
||||||
|
AddStep("move cursor to top left", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft));
|
||||||
|
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
|
||||||
|
AddStep("move cursor to top right", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopRight));
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
|
AddSliderStep("cursor size", 0.1f, 2f, 1f, v => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +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 osu.Framework.Audio;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Overlays.Settings;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
|
||||||
{
|
|
||||||
public class OsuModRateAdjustConcrete : ModRateAdjustConcrete
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -232,10 +232,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
case ModType.Special:
|
case ModType.Special:
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
return new Mod[]
|
return Array.Empty<Mod>();
|
||||||
{
|
|
||||||
new OsuModRateAdjustConcrete(),
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
leaderboard.Origin = Anchor.BottomLeft;
|
leaderboard.Origin = Anchor.BottomLeft;
|
||||||
leaderboard.Position = pos;
|
leaderboard.Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
|
|||||||
@@ -49,6 +49,18 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool AllowPartRotation { get; set; }
|
protected bool AllowPartRotation { get; set; }
|
||||||
|
|
||||||
|
private Vector2 cursorScale;
|
||||||
|
|
||||||
|
public Vector2 CursorScale
|
||||||
|
{
|
||||||
|
get => cursorScale;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
cursorScale = value;
|
||||||
|
Invalidate(Invalidation.DrawNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The trail part texture origin.
|
/// The trail part texture origin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -233,6 +245,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
private float time;
|
private float time;
|
||||||
private float fadeExponent;
|
private float fadeExponent;
|
||||||
private float angle;
|
private float angle;
|
||||||
|
private Vector2 cursorScale;
|
||||||
|
|
||||||
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
||||||
private Vector2 originPosition;
|
private Vector2 originPosition;
|
||||||
@@ -253,6 +266,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
time = Source.time;
|
time = Source.time;
|
||||||
fadeExponent = Source.FadeExponent;
|
fadeExponent = Source.FadeExponent;
|
||||||
angle = Source.AllowPartRotation ? float.DegreesToRadians(Source.PartRotation) : 0;
|
angle = Source.AllowPartRotation ? float.DegreesToRadians(Source.PartRotation) : 0;
|
||||||
|
cursorScale = Source.cursorScale;
|
||||||
|
|
||||||
originPosition = Vector2.Zero;
|
originPosition = Vector2.Zero;
|
||||||
|
|
||||||
@@ -307,7 +321,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
vertexBatch.Add(new TexturedTrailVertex
|
vertexBatch.Add(new TexturedTrailVertex
|
||||||
{
|
{
|
||||||
Position = rotateAround(
|
Position = rotateAround(
|
||||||
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y),
|
new Vector2(
|
||||||
|
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
|
||||||
|
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
|
||||||
part.Position, sin, cos),
|
part.Position, sin, cos),
|
||||||
TexturePosition = textureRect.BottomLeft,
|
TexturePosition = textureRect.BottomLeft,
|
||||||
TextureRect = new Vector4(0, 0, 1, 1),
|
TextureRect = new Vector4(0, 0, 1, 1),
|
||||||
@@ -318,8 +334,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
vertexBatch.Add(new TexturedTrailVertex
|
vertexBatch.Add(new TexturedTrailVertex
|
||||||
{
|
{
|
||||||
Position = rotateAround(
|
Position = rotateAround(
|
||||||
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X,
|
new Vector2(
|
||||||
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y), part.Position, sin, cos),
|
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
|
||||||
|
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
|
||||||
|
part.Position, sin, cos),
|
||||||
TexturePosition = textureRect.BottomRight,
|
TexturePosition = textureRect.BottomRight,
|
||||||
TextureRect = new Vector4(0, 0, 1, 1),
|
TextureRect = new Vector4(0, 0, 1, 1),
|
||||||
Colour = DrawColourInfo.Colour.BottomRight.Linear,
|
Colour = DrawColourInfo.Colour.BottomRight.Linear,
|
||||||
@@ -329,7 +347,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
vertexBatch.Add(new TexturedTrailVertex
|
vertexBatch.Add(new TexturedTrailVertex
|
||||||
{
|
{
|
||||||
Position = rotateAround(
|
Position = rotateAround(
|
||||||
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
|
new Vector2(
|
||||||
|
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
|
||||||
|
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
|
||||||
part.Position, sin, cos),
|
part.Position, sin, cos),
|
||||||
TexturePosition = textureRect.TopRight,
|
TexturePosition = textureRect.TopRight,
|
||||||
TextureRect = new Vector4(0, 0, 1, 1),
|
TextureRect = new Vector4(0, 0, 1, 1),
|
||||||
@@ -340,7 +360,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
vertexBatch.Add(new TexturedTrailVertex
|
vertexBatch.Add(new TexturedTrailVertex
|
||||||
{
|
{
|
||||||
Position = rotateAround(
|
Position = rotateAround(
|
||||||
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
|
new Vector2(
|
||||||
|
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
|
||||||
|
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
|
||||||
part.Position, sin, cos),
|
part.Position, sin, cos),
|
||||||
TexturePosition = textureRect.TopLeft,
|
TexturePosition = textureRect.TopLeft,
|
||||||
TextureRect = new Vector4(0, 0, 1, 1),
|
TextureRect = new Vector4(0, 0, 1, 1),
|
||||||
|
|||||||
@@ -64,8 +64,14 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
var newScale = new Vector2(e.NewValue);
|
var newScale = new Vector2(e.NewValue);
|
||||||
|
|
||||||
rippleVisualiser.CursorScale = newScale;
|
rippleVisualiser.CursorScale = newScale;
|
||||||
cursorTrail.Scale = newScale;
|
updateTrailScale();
|
||||||
}, true);
|
}, true);
|
||||||
|
cursorTrail.OnSkinChanged += updateTrailScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTrailScale()
|
||||||
|
{
|
||||||
|
if (cursorTrail.Drawable is CursorTrail trail) trail.CursorScale = new Vector2(ActiveCursor.CursorScale.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int downCount;
|
private int downCount;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
|
|||||||
spectatorList.Anchor = Anchor.BottomLeft;
|
spectatorList.Anchor = Anchor.BottomLeft;
|
||||||
spectatorList.Origin = Anchor.TopLeft;
|
spectatorList.Origin = Anchor.TopLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
|||||||
spectatorList.Origin = Anchor.TopLeft;
|
spectatorList.Origin = Anchor.TopLeft;
|
||||||
spectatorList.Position = new Vector2(320, -280);
|
spectatorList.Position = new Vector2(320, -280);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
|||||||
spectatorList.Origin = Anchor.TopLeft;
|
spectatorList.Origin = Anchor.TopLeft;
|
||||||
spectatorList.Position = pos;
|
spectatorList.Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
new LegacyDefaultComboCounter(),
|
new LegacyDefaultComboCounter(),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
public void OneTimeSetUp()
|
public void OneTimeSetUp()
|
||||||
{
|
{
|
||||||
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
||||||
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
|
MessageFormatter.WebsiteRootUrl = "osu.jvnko.boats";
|
||||||
}
|
}
|
||||||
|
|
||||||
[OneTimeTearDown]
|
[OneTimeTearDown]
|
||||||
@@ -47,11 +47,11 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSupportedProtocolLinkParsing()
|
public void TestSupportedProtocolLinkParsing()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://dev.ppy.sh joinmyosump://12345 jointheosu://chan/#english" });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://osu.jvnko.boats joinmyjvnkosump://12345 jointhejvnkosu://chan/#english" });
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats", result.Links[0].Url);
|
||||||
Assert.AreEqual("osump://12345", result.Links[1].Url);
|
Assert.AreEqual("jvnkosump://12345", result.Links[1].Url);
|
||||||
Assert.AreEqual("osu://chan/#english", result.Links[2].Url);
|
Assert.AreEqual("jvnkosu://chan/#english", result.Links[2].Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -66,15 +66,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(36, result.Links[0].Length);
|
Assert.AreEqual(36, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456?whatever")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123/456")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc/def", "https://osu.jvnko.boats/beatmapsets/abc/def")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123/whatever")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc", "https://osu.jvnko.boats/beatmapsets/abc")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions", "https://dev.ppy.sh/beatmapsets/discussions")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions", "https://osu.jvnko.boats/beatmapsets/discussions")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions/123", "https://osu.jvnko.boats/beatmapsets/discussions/123")]
|
||||||
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
||||||
@@ -150,7 +150,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
|
|
||||||
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
@@ -163,15 +163,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(3, result.Links.Count);
|
Assert.AreEqual(3, result.Links.Count);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki:Link", result.Links[1].Url);
|
||||||
Assert.AreEqual(20, result.Links[1].Index);
|
Assert.AreEqual(20, result.Links[1].Index);
|
||||||
Assert.AreEqual(9, result.Links[1].Length);
|
Assert.AreEqual(9, result.Links[1].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki.Link", result.Links[2].Url);
|
||||||
Assert.AreEqual(29, result.Links[2].Index);
|
Assert.AreEqual(29, result.Links[2].Index);
|
||||||
Assert.AreEqual(9, result.Links[2].Length);
|
Assert.AreEqual(9, result.Links[2].Length);
|
||||||
}
|
}
|
||||||
@@ -452,7 +452,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
||||||
Assert.AreEqual(26, result.Links[0].Index);
|
Assert.AreEqual(26, result.Links[0].Index);
|
||||||
Assert.AreEqual(19, result.Links[0].Length);
|
Assert.AreEqual(23, result.Links[0].Length);
|
||||||
|
|
||||||
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
||||||
|
|
||||||
@@ -467,13 +467,13 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOsuMpProtocol()
|
public void TestOsuMpProtocol()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game osump://12346." });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game jvnkosump://12346." });
|
||||||
|
|
||||||
Assert.AreEqual(result.Content, result.DisplayContent);
|
Assert.AreEqual(result.Content, result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("osump://12346", result.Links[0].Url);
|
Assert.AreEqual("jvnkosump://12346", result.Links[0].Url);
|
||||||
Assert.AreEqual(25, result.Links[0].Index);
|
Assert.AreEqual(25, result.Links[0].Index);
|
||||||
Assert.AreEqual(13, result.Links[0].Length);
|
Assert.AreEqual(17, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -499,7 +499,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
||||||
Assert.AreEqual(4, result.Links.Count);
|
Assert.AreEqual(4, result.Links.Count);
|
||||||
|
|
||||||
Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
|
Link f = result.Links.Find(l => l.Url == "https://osu.jvnko.boats/wiki/wiki links");
|
||||||
Assert.That(f, Is.Not.Null);
|
Assert.That(f, Is.Not.Null);
|
||||||
Assert.AreEqual(44, f.Index);
|
Assert.AreEqual(44, f.Index);
|
||||||
Assert.AreEqual(10, f.Length);
|
Assert.AreEqual(10, f.Length);
|
||||||
@@ -554,8 +554,8 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("/relative", result.Argument);
|
Assert.AreEqual("/relative", result.Argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog", "")]
|
[TestCase("https://osu.jvnko.boats/home/changelog", "")]
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
[TestCase("https://osu.jvnko.boats/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
||||||
public void TestChangelogLinks(string link, string expectedArg)
|
public void TestChangelogLinks(string link, string expectedArg)
|
||||||
{
|
{
|
||||||
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
||||||
|
|||||||
@@ -134,10 +134,12 @@ namespace osu.Game.Tests.Mods
|
|||||||
|
|
||||||
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
||||||
|
|
||||||
|
// WARNING: this only makes sense for debug builds which have very extended limits
|
||||||
|
// release builds still use sane values
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(0).And.LessThanOrEqualTo(11));
|
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
|
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
|
|||||||
Assert.NotNull(converted);
|
Assert.NotNull(converted);
|
||||||
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
||||||
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
||||||
Assert.That(converted.Acronym, Is.EqualTo("WNG??"));
|
Assert.That(converted.Acronym, Is.EqualTo("WNG!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ namespace osu.Game.Tests.Online
|
|||||||
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(10), cancellationToken))
|
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(30), cancellationToken))
|
||||||
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
||||||
|
|
||||||
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
||||||
|
|||||||
BIN
osu.Game.Tests/Resources/Archives/modified-classic-20250827.osk
Normal file
BIN
osu.Game.Tests/Resources/special-skin/score-0@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-1@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-2@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-3@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-4@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-5@2x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-6@2x.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-7@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-8@2x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-9@2x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-comma@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-dot@2x.png
Normal file
|
After Width: | Height: | Size: 930 B |
BIN
osu.Game.Tests/Resources/special-skin/score-percent@2x.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-pp@2x.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
osu.Game.Tests/Resources/special-skin/score-x@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
@@ -79,8 +79,12 @@ namespace osu.Game.Tests.Skins
|
|||||||
"Archives/modified-argon-20250424.osk",
|
"Archives/modified-argon-20250424.osk",
|
||||||
// Covers "Argon" unstable rate counter
|
// Covers "Argon" unstable rate counter
|
||||||
"Archives/modified-argon-20250809.osk",
|
"Archives/modified-argon-20250809.osk",
|
||||||
|
// Covers legacy style performance points counter
|
||||||
|
"Archives/modified-classic-20250827.osk",
|
||||||
// Covers "Argon" judgement counter
|
// Covers "Argon" judgement counter
|
||||||
"Archives/modified-argon-20250308.osk",
|
"Archives/modified-argon-20250308.osk",
|
||||||
|
// Covers "Argon" clicks/s counter, longest combo counter, skinnable SR display and beatmap status pill
|
||||||
|
"Archives/modified-argon-20251215-jvnkosu.osk",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
AddStep("create thumbnail", () =>
|
AddStep("create thumbnail", () =>
|
||||||
{
|
{
|
||||||
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
|
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
|
||||||
beatmapSet.OnlineID = 241526; // ID hardcoded to ensure that the preview track exists online.
|
beatmapSet.OnlineID = 1; // ID hardcoded to ensure that the preview track exists online.
|
||||||
|
|
||||||
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet, beatmapSet)
|
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet, beatmapSet)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
setUpEditor(new OsuRuleset().RulesetInfo);
|
setUpEditor(new OsuRuleset().RulesetInfo);
|
||||||
AddAssert("is osu! ruleset", () => editorBeatmap.BeatmapInfo.Ruleset.Equals(new OsuRuleset().RulesetInfo));
|
AddAssert("is osu! ruleset", () => editorBeatmap.BeatmapInfo.Ruleset.Equals(new OsuRuleset().RulesetInfo));
|
||||||
|
|
||||||
AddStep("jump to encoded link", () => Game.HandleLink("osu://edit/00:14:142%20(1)"));
|
AddStep("jump to encoded link", () => Game.HandleLink("jvnkosu://edit/00:14:142%20(1)"));
|
||||||
|
|
||||||
AddUntilStep("wait for seek", () => editorClock.SeekingOrStopped.Value);
|
AddUntilStep("wait for seek", () => editorClock.SeekingOrStopped.Value);
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,34 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Texture == null)));
|
sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Texture == null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSpriteFadeOverflowBehaviour()
|
||||||
|
{
|
||||||
|
AddStep("create sprite", () => SetContents(_ =>
|
||||||
|
{
|
||||||
|
var layer = storyboard.GetLayer("Background");
|
||||||
|
|
||||||
|
var sprite = new StoryboardSprite(lookup_name, Anchor.TopLeft, new Vector2(256, 192));
|
||||||
|
sprite.Commands.AddAlpha(Easing.None, Time.Current, Time.Current + 2000, 0, 2);
|
||||||
|
|
||||||
|
layer.Elements.Clear();
|
||||||
|
layer.Add(sprite);
|
||||||
|
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
storyboard.CreateDrawable()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddUntilStep("sprite reached high opacity once", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
|
||||||
|
AddUntilStep("sprite reset to low opacity", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha < 0.2f)));
|
||||||
|
AddUntilStep("sprite reached high opacity twice", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLookupFromStoryboard()
|
public void TestLookupFromStoryboard()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
checkKey(() => counter, 0, false);
|
checkKey(() => counter, 0, false);
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
@@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
checkKey(() => counter, 0, false);
|
checkKey(() => counter, 0, false);
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
@@ -150,8 +150,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counterX = null!;
|
KeyCounter counterX = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -204,8 +204,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counterX = null!;
|
KeyCounter counterX = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
@@ -247,7 +247,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new ManiaRuleset());
|
loadPlayer(() => new ManiaRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
|
||||||
|
|
||||||
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
AddStep("press space", () => InputManager.PressKey(Key.Space));
|
||||||
checkKey(() => counter, 1, true);
|
checkKey(() => counter, 1, true);
|
||||||
@@ -271,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
|
|
||||||
AddStep("pause", () => Player.Pause());
|
AddStep("pause", () => Player.Pause());
|
||||||
AddStep("resume", () => Player.Resume());
|
AddStep("resume", () => Player.Resume());
|
||||||
@@ -297,7 +297,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
KeyCounter counter = null!;
|
KeyCounter counter = null!;
|
||||||
|
|
||||||
loadPlayer(() => new OsuRuleset());
|
loadPlayer(() => new OsuRuleset());
|
||||||
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
|
||||||
|
|
||||||
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
AddStep("press Z", () => InputManager.PressKey(Key.Z));
|
||||||
AddAssert("circle hit", () => Player.ScoreProcessor.HighestCombo.Value, () => Is.EqualTo(1));
|
AddAssert("circle hit", () => Player.ScoreProcessor.HighestCombo.Value, () => Is.EqualTo(1));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using osu.Game.Rulesets.Osu.Scoring;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Skinning.Triangles;
|
using osu.Game.Skinning.Triangles;
|
||||||
using osu.Game.Tests.Gameplay;
|
using osu.Game.Tests.Gameplay;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
protected override Drawable CreateDefaultImplementation() => new TrianglesPerformancePointsCounter();
|
protected override Drawable CreateDefaultImplementation() => new TrianglesPerformancePointsCounter();
|
||||||
protected override Drawable CreateArgonImplementation() => new ArgonPerformancePointsCounter();
|
protected override Drawable CreateArgonImplementation() => new ArgonPerformancePointsCounter();
|
||||||
protected override Drawable CreateLegacyImplementation() => Empty();
|
protected override Drawable CreateLegacyImplementation() => new LegacyPerformancePointsCounter();
|
||||||
|
|
||||||
private Bindable<JudgementResult> lastJudgementResult => (Bindable<JudgementResult>)gameplayState.LastJudgementResult;
|
private Bindable<JudgementResult> lastJudgementResult => (Bindable<JudgementResult>)gameplayState.LastJudgementResult;
|
||||||
|
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
if (!AllowLoad.Wait(TimeSpan.FromSeconds(10)))
|
if (!AllowLoad.Wait(TimeSpan.FromSeconds(30)))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
@@ -378,6 +379,23 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
() => Is.EqualTo(3));
|
() => Is.EqualTo(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCopyPasteIdempotency()
|
||||||
|
{
|
||||||
|
string state = null!;
|
||||||
|
AddStep("select everything", () => InputManager.Keys(PlatformAction.SelectAll));
|
||||||
|
AddStep("dump state", () =>
|
||||||
|
{
|
||||||
|
state = JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray());
|
||||||
|
});
|
||||||
|
AddStep("copy", () => InputManager.Keys(PlatformAction.Copy));
|
||||||
|
AddStep("delete", () => InputManager.Keys(PlatformAction.Delete));
|
||||||
|
AddStep("paste", () => InputManager.Keys(PlatformAction.Paste));
|
||||||
|
AddAssert("pasted state equals dumped",
|
||||||
|
() => JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray()),
|
||||||
|
() => Is.EqualTo(state));
|
||||||
|
}
|
||||||
|
|
||||||
private SkinnableContainer globalHUDTarget => Player.ChildrenOfType<SkinnableContainer>()
|
private SkinnableContainer globalHUDTarget => Player.ChildrenOfType<SkinnableContainer>()
|
||||||
.Single(c => c.Lookup.Lookup == GlobalSkinnableContainers.MainHUDComponents && c.Lookup.Ruleset == null);
|
.Single(c => c.Lookup.Lookup == GlobalSkinnableContainers.MainHUDComponents && c.Lookup.Ruleset == null);
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("check request received", () =>
|
AddStep("check request received", () =>
|
||||||
{
|
{
|
||||||
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
||||||
req.Duration == TimeSpan.FromSeconds(10)
|
req.Duration == TimeSpan.FromSeconds(30)
|
||||||
)), Times.Once);
|
)), Times.Once);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("check request received", () =>
|
AddStep("check request received", () =>
|
||||||
{
|
{
|
||||||
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
|
||||||
req.Duration == TimeSpan.FromSeconds(10)
|
req.Duration == TimeSpan.FromSeconds(30)
|
||||||
)), Times.Once);
|
)), Times.Once);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -305,6 +305,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
|
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
|
||||||
new APIMod(new OsuModStrictTracking()),
|
new APIMod(new OsuModStrictTracking()),
|
||||||
|
new APIMod(new OsuModAutoplay()), // THIS IS PURELY TO ENABLE UNRANKED BADGE AND LET TEST PASS
|
||||||
|
// I AM NOT PROUD OF THIS
|
||||||
},
|
},
|
||||||
AllowedMods = new[]
|
AllowedMods = new[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
// Importantly, this occurs before base.load().
|
// Importantly, this occurs before base.load().
|
||||||
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(10)))
|
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(30)))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
||||||
return base.CreateChildDependencies(parent);
|
return base.CreateChildDependencies(parent);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Graphics.Carousel;
|
using osu.Game.Graphics.Carousel;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.Notifications.WebSocket;
|
using osu.Game.Online.Notifications.WebSocket;
|
||||||
@@ -33,6 +34,7 @@ using osu.Game.Overlays.BeatmapListing;
|
|||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Overlays.Toolbar;
|
using osu.Game.Overlays.Toolbar;
|
||||||
|
using osu.Game.Overlays.Volume;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
@@ -920,8 +922,12 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
[Explicit("Featured Artist dialog is never displayed as the filter is disabled by default.")]
|
||||||
public void TestFeaturedArtistDisclaimerDialog()
|
public void TestFeaturedArtistDisclaimerDialog()
|
||||||
{
|
{
|
||||||
|
// NO-OP: FA dialog is not displayed ever
|
||||||
|
|
||||||
|
/*
|
||||||
BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType<BeatmapListingOverlay>().FirstOrDefault();
|
BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType<BeatmapListingOverlay>().FirstOrDefault();
|
||||||
|
|
||||||
AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty));
|
AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty));
|
||||||
@@ -939,6 +945,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("dialog dismissed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog == null);
|
AddAssert("dialog dismissed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog == null);
|
||||||
|
|
||||||
AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -1331,6 +1338,34 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("still nothing selected", () => Game.Beatmap.IsDefault);
|
AddAssert("still nothing selected", () => Game.Beatmap.IsDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestVolumeMeterDragDoesNotDismissFocusedOverlay()
|
||||||
|
{
|
||||||
|
AddStep("show beatmap overlay", () => Game.ShowBeatmapSet(1));
|
||||||
|
AddUntilStep("beatmap overlay still visible",
|
||||||
|
() => Game.ChildrenOfType<BeatmapSetOverlay>().SingleOrDefault()?.State.Value,
|
||||||
|
() => Is.EqualTo(Visibility.Visible));
|
||||||
|
AddStep("set game volume to max", () => Game.Dependencies.Get<FrameworkConfigManager>().SetValue(FrameworkSetting.VolumeUniversal, 1d));
|
||||||
|
AddStep("move to centre", () => InputManager.MoveMouseTo(Game));
|
||||||
|
AddStep("alt-scroll down", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.AltLeft);
|
||||||
|
InputManager.ScrollVerticalBy(-1);
|
||||||
|
InputManager.ReleaseKey(Key.AltLeft);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for volume overlay to show", () => Game.ChildrenOfType<VolumeOverlay>().SingleOrDefault()?.State.Value, () => Is.EqualTo(Visibility.Visible));
|
||||||
|
AddStep("start dragging meter", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(Game.ChildrenOfType<VolumeMeter>().First().ChildrenOfType<OsuSpriteText>().First());
|
||||||
|
InputManager.PressButton(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddStep("drag away", () => InputManager.MoveMouseTo(Game.ChildrenOfType<VolumeMeter>().First().ChildrenOfType<OsuSpriteText>().First(), new Vector2(0, -100)));
|
||||||
|
AddStep("release mouse", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
AddAssert("beatmap overlay still visible",
|
||||||
|
() => Game.ChildrenOfType<BeatmapSetOverlay>().SingleOrDefault()?.State.Value,
|
||||||
|
() => Is.EqualTo(Visibility.Visible));
|
||||||
|
}
|
||||||
|
|
||||||
private Func<Player> playToResults()
|
private Func<Player> playToResults()
|
||||||
{
|
{
|
||||||
var player = playToCompletion();
|
var player = playToCompletion();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
private const int requested_beatmap_id = 75;
|
private const int requested_beatmap_id = 75;
|
||||||
private const int requested_beatmap_set_id = 1;
|
private const int requested_beatmap_set_id = 1;
|
||||||
|
|
||||||
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://b/{requested_beatmap_id}" });
|
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://b/{requested_beatmap_id}" });
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
{
|
{
|
||||||
private const int requested_beatmap_set_id = 1;
|
private const int requested_beatmap_set_id = 1;
|
||||||
|
|
||||||
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://s/{requested_beatmap_set_id}" });
|
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://s/{requested_beatmap_set_id}" });
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
public void TestFeaturedArtistFilter()
|
public void TestFeaturedArtistFilter()
|
||||||
{
|
{
|
||||||
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
|
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
|
||||||
AddAssert("featured artist filter is on", () => overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
|
||||||
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
|
|
||||||
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
|
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
|
||||||
|
AddAssert("featured artist filter is on", () => overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -55,31 +55,31 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
});
|
});
|
||||||
|
|
||||||
[TestCase("test!")]
|
[TestCase("test!")]
|
||||||
[TestCase("dev.ppy.sh!")]
|
[TestCase("osu.jvnko.boats!")]
|
||||||
[TestCase("https://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("https://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("http://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("http://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("forgothttps://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("forgothttps://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("forgothttp://dev.ppy.sh!", LinkAction.External)]
|
[TestCase("forgothttp://osu.jvnko.boats!", LinkAction.External)]
|
||||||
[TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
|
||||||
[TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)]
|
[TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)]
|
||||||
[TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)]
|
[TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)]
|
||||||
[TestCase("(osu forums)[https://dev.ppy.sh/forum] (old link format)", LinkAction.External)]
|
[TestCase("(osu forums)[https://osu.jvnko.boats/forum] (old link format)", LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home New site] (new link format)", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home New site] (new link format)", LinkAction.External)]
|
||||||
[TestCase("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", LinkAction.External)]
|
[TestCase("[osu forums](https://osu.jvnko.boats/forum) (new link format 2)", LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
|
||||||
[TestCase("Let's (try)[https://dev.ppy.sh/home] [https://dev.ppy.sh/b/252238 multiple links] https://dev.ppy.sh/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
|
[TestCase("Let's (try)[https://osu.jvnko.boats/home] [https://osu.jvnko.boats/b/252238 multiple links] https://osu.jvnko.boats/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
|
||||||
[TestCase("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
|
[TestCase("[https://osu.jvnko.boats/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
|
||||||
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", LinkAction.External)]
|
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://osu.jvnko.boats/home)", LinkAction.External)]
|
||||||
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
|
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://osu.jvnko.boats/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
|
||||||
[TestCase("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).")] // note that there's 0 links here (they get removed if a channel is not found)
|
[TestCase("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).")] // note that there's 0 links here (they get removed if a channel is not found)
|
||||||
[TestCase("Join my multiplayer game osu://room/12346.", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer game jvnkosu://room/12346.", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my multiplayer gameosu://room/12346.", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer gamejvnkosu://room/12346.", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my [multiplayer game](osu://room/12346).", LinkAction.JoinRoom)]
|
[TestCase("Join my [multiplayer game](jvnkosu://room/12346).", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my multiplayer game http://dev.ppy.sh/multiplayer/rooms/12346", LinkAction.JoinRoom)]
|
[TestCase("Join my multiplayer game http://osu.jvnko.boats/multiplayer/rooms/12346", LinkAction.JoinRoom)]
|
||||||
[TestCase("Join my [multiplayer game](http://dev.ppy.sh/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
|
[TestCase("Join my [multiplayer game](http://osu.jvnko.boats/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
|
||||||
[TestCase($"Join my [#english]({OsuGameBase.OSU_PROTOCOL}chan/#english).", LinkAction.OpenChannel)]
|
[TestCase($"Join my [#english]({OsuGameBase.OSU_PROTOCOL}chan/#english).", LinkAction.OpenChannel)]
|
||||||
[TestCase($"Join my {OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
[TestCase($"Join my {OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
||||||
[TestCase($"Join my{OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
[TestCase($"Join my{OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
|
||||||
@@ -91,11 +91,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
addMessageWithChecks(text, expectedActions: actions);
|
addMessageWithChecks(text, expectedActions: actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("is now listening to [https://dev.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
|
[TestCase("is now listening to [https://osu.jvnko.boats/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
|
||||||
[TestCase("is now playing [https://dev.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
|
[TestCase("is now playing [https://osu.jvnko.boats/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
|
||||||
[TestCase("I am important!", false, true)]
|
[TestCase("I am important!", false, true)]
|
||||||
[TestCase("feels important", true, true)]
|
[TestCase("feels important", true, true)]
|
||||||
[TestCase("likes to post this [https://dev.ppy.sh/home link].", true, true, LinkAction.External)]
|
[TestCase("likes to post this [https://osu.jvnko.boats/home link].", true, true, LinkAction.External)]
|
||||||
public void TestActionAndImportantLinks(string text, bool isAction, bool isImportant, params LinkAction[] expectedActions)
|
public void TestActionAndImportantLinks(string text, bool isAction, bool isImportant, params LinkAction[] expectedActions)
|
||||||
{
|
{
|
||||||
addMessageWithChecks(text, isAction, isImportant, expectedActions);
|
addMessageWithChecks(text, isAction, isImportant, expectedActions);
|
||||||
@@ -135,9 +135,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
int messageIndex = 0;
|
int messageIndex = 0;
|
||||||
|
|
||||||
addEchoWithWait("sent!", "received!");
|
addEchoWithWait("sent!", "received!");
|
||||||
addEchoWithWait("https://dev.ppy.sh/home", null, 500);
|
addEchoWithWait("https://osu.jvnko.boats/home", null, 500);
|
||||||
addEchoWithWait("[https://dev.ppy.sh/forum let's try multiple words too!]");
|
addEchoWithWait("[https://osu.jvnko.boats/forum let's try multiple words too!]");
|
||||||
addEchoWithWait("(long loading times! clickable while loading?)[https://dev.ppy.sh/home]", null, 5000);
|
addEchoWithWait("(long loading times! clickable while loading?)[https://osu.jvnko.boats/home]", null, 5000);
|
||||||
|
|
||||||
void addEchoWithWait(string text, string? completeText = null, double delay = 250)
|
void addEchoWithWait(string text, string? completeText = null, double delay = 250)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("show example score", () =>
|
AddStep("show example score", () =>
|
||||||
{
|
{
|
||||||
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
|
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
|
||||||
score.Mods = score.Mods.Append(new OsuModDifficultyAdjust()).ToArray();
|
score.Mods = score.Mods.Append(new OsuModAutoplay()).ToArray();
|
||||||
showPanel(score);
|
showPanel(score);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
private void testInfoLabels(int expectedCount)
|
private void testInfoLabels(int expectedCount)
|
||||||
{
|
{
|
||||||
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
|
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
|
||||||
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() == expectedCount);
|
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() >= expectedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
assertGroup(results, 3, "Pending", pendingBeatmap.Beatmaps, ref total);
|
assertGroup(results, 3, "Pending", pendingBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 4, "Graveyard", graveyardBeatmap.Beatmaps, ref total);
|
assertGroup(results, 4, "Graveyard", graveyardBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 5, "Local", localBeatmap.Beatmaps, ref total);
|
assertGroup(results, 5, "Local", localBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 6, "Unknown", noneBeatmap.Beatmaps, ref total);
|
assertGroup(results, 6, "Offline", noneBeatmap.Beatmaps, ref total);
|
||||||
assertGroup(results, 7, "Loved", lovedBeatmap.Beatmaps, ref total);
|
assertGroup(results, 7, "Loved", lovedBeatmap.Beatmaps, ref total);
|
||||||
assertTotal(results, total);
|
assertTotal(results, total);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUnrankedBadge()
|
public void TestUnrankedBadge()
|
||||||
{
|
{
|
||||||
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
|
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
|
||||||
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
|
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
|
||||||
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
||||||
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
|
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUnrankedBadge()
|
public void TestUnrankedBadge()
|
||||||
{
|
{
|
||||||
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
|
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
|
||||||
AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
|
AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
|
||||||
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
|
||||||
AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);
|
AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
setSliderValue("Circle Size", 99);
|
setSliderValue("Circle Size", 99);
|
||||||
|
|
||||||
checkSliderAtValue("Circle Size", 11);
|
// debug build maximum value
|
||||||
checkBindableAtValue("Circle Size", 11);
|
checkSliderAtValue("Circle Size", 13);
|
||||||
|
checkBindableAtValue("Circle Size", 13);
|
||||||
|
|
||||||
setSliderValue("Approach Rate", -5);
|
setSliderValue("Approach Rate", -5);
|
||||||
|
|
||||||
|
|||||||
@@ -207,23 +207,23 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
||||||
|
|
||||||
ModSelectColumn lastColumn = null!;
|
ModSelectColumn secondColumn = null!;
|
||||||
|
|
||||||
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
|
AddAssert("second column dimmed", () => !this.ChildrenOfType<ModColumn>().ElementAt(2).Active.Value);
|
||||||
AddStep("request scroll to last column", () =>
|
AddStep("request scroll to second column", () =>
|
||||||
{
|
{
|
||||||
var lastDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().Last();
|
var secondDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().ElementAt(2);
|
||||||
lastColumn = lastDimContainer.Column;
|
secondColumn = secondDimContainer.Column;
|
||||||
lastDimContainer.RequestScroll?.Invoke(lastDimContainer);
|
secondDimContainer.RequestScroll?.Invoke(secondDimContainer);
|
||||||
});
|
});
|
||||||
AddUntilStep("column undimmed", () => lastColumn.Active.Value);
|
AddUntilStep("column undimmed", () => secondColumn.Active.Value);
|
||||||
|
|
||||||
AddStep("click panel", () =>
|
AddStep("click panel", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(lastColumn.ChildrenOfType<ModPanel>().First());
|
InputManager.MoveMouseTo(secondColumn.ChildrenOfType<ModPanel>().First());
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
AddUntilStep("panel selected", () => lastColumn.ChildrenOfType<ModPanel>().First().Active.Value);
|
AddUntilStep("panel selected", () => secondColumn.ChildrenOfType<ModPanel>().First().Active.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -810,7 +810,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||||
|
|
||||||
AddStep("unset filter", () => modSelectOverlay.IsValidMod = _ => true);
|
AddStep("unset filter", () => modSelectOverlay.IsValidMod = _ => true);
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("filter out everything", () => modSelectOverlay.IsValidMod = _ => false);
|
AddStep("filter out everything", () => modSelectOverlay.IsValidMod = _ => false);
|
||||||
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||||
@@ -839,7 +839,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
waitForColumnLoad();
|
waitForColumnLoad();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
|
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
|
||||||
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||||
@@ -848,7 +848,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||||
|
|
||||||
AddStep("clear search bar", () => modSelectOverlay.SearchTerm = "");
|
AddStep("clear search bar", () => modSelectOverlay.SearchTerm = "");
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -863,7 +863,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
waitForColumnLoad();
|
waitForColumnLoad();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
|
|
||||||
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
|
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
|
||||||
AddAssert("one column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
AddAssert("one column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
||||||
@@ -871,7 +871,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("hide", () => modSelectOverlay.Hide());
|
AddStep("hide", () => modSelectOverlay.Hide());
|
||||||
AddStep("show", () => modSelectOverlay.Show());
|
AddStep("show", () => modSelectOverlay.Show());
|
||||||
|
|
||||||
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -880,13 +880,13 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
createScreen();
|
createScreen();
|
||||||
|
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
|
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
|
||||||
|
|
||||||
AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
|
AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
|
||||||
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
|
||||||
|
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
|
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// 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 System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
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.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Framework.Input.Handlers.Tablet;
|
||||||
using osu.Framework.Layout;
|
using osu.Framework.Layout;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
@@ -50,6 +52,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
private RectangleF? customRect;
|
private RectangleF? customRect;
|
||||||
private bool customRectIsRelativePosition;
|
private bool customRectIsRelativePosition;
|
||||||
|
|
||||||
|
private ITabletHandler? tabletHandler;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set a custom position and scale which overrides any user specification.
|
/// Set a custom position and scale which overrides any user specification.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,7 +127,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, ISafeArea safeArea)
|
private void load(GameHost host, OsuConfigManager config, ISafeArea safeArea)
|
||||||
{
|
{
|
||||||
scalingMode = config.GetBindable<ScalingMode>(OsuSetting.Scaling);
|
scalingMode = config.GetBindable<ScalingMode>(OsuSetting.Scaling);
|
||||||
scalingMode.ValueChanged += _ => Scheduler.AddOnce(updateSize);
|
scalingMode.ValueChanged += _ => Scheduler.AddOnce(updateSize);
|
||||||
@@ -148,6 +152,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
scalingMenuBackgroundDim = config.GetBindable<float>(OsuSetting.ScalingBackgroundDim);
|
scalingMenuBackgroundDim = config.GetBindable<float>(OsuSetting.ScalingBackgroundDim);
|
||||||
scalingMenuBackgroundDim.ValueChanged += _ => Scheduler.AddOnce(updateSize);
|
scalingMenuBackgroundDim.ValueChanged += _ => Scheduler.AddOnce(updateSize);
|
||||||
|
|
||||||
|
tabletHandler = host.AvailableInputHandlers.OfType<ITabletHandler>().SingleOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@@ -222,6 +228,13 @@ namespace osu.Game.Graphics.Containers
|
|||||||
// An example of how this can occur is when the skin editor is visible and the game screen scaling is set to "Everything".
|
// An example of how this can occur is when the skin editor is visible and the game screen scaling is set to "Everything".
|
||||||
sizableContainer.TransformTo(nameof(CornerRadius), requiresMasking ? corner_radius : 0, TRANSITION_DURATION, requiresMasking ? Easing.OutQuart : Easing.None)
|
sizableContainer.TransformTo(nameof(CornerRadius), requiresMasking ? corner_radius : 0, TRANSITION_DURATION, requiresMasking ? Easing.OutQuart : Easing.None)
|
||||||
.OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
|
.OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
|
||||||
|
|
||||||
|
// when "everything" scaling mode is active, tablets are expected to constrain output area to the scaled size of the game
|
||||||
|
if (tabletHandler != null)
|
||||||
|
{
|
||||||
|
tabletHandler.OutputAreaSize.Value = scalingMode.Value == ScalingMode.Everything ? new Vector2(sizeX.Value, sizeY.Value) : Vector2.One;
|
||||||
|
tabletHandler.OutputAreaOffset.Value = scalingMode.Value == ScalingMode.Everything ? new Vector2(posX.Value, posY.Value) : new Vector2(0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private partial class ScalingBackgroundScreen : BackgroundScreenDefault
|
private partial class ScalingBackgroundScreen : BackgroundScreenDefault
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
protected OverlayColourProvider ColourProvider { get; private set; } = null!;
|
protected OverlayColourProvider? ColourProvider { get; private set; } = null!;
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly OsuSpriteText text;
|
private readonly OsuSpriteText text;
|
||||||
@@ -190,9 +190,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
var colourDark = darkerColour ?? ColourProvider.Background3;
|
var colourDark = darkerColour ?? ColourProvider?.Background3 ?? Colour4.DarkGray;
|
||||||
var colourLight = lighterColour ?? ColourProvider.Background1;
|
var colourLight = lighterColour ?? ColourProvider?.Background1 ?? Colour4.LightGray;
|
||||||
var colourContent = textColour ?? ColourProvider.Content1;
|
var colourContent = textColour ?? ColourProvider?.Content1 ?? Colour4.White;
|
||||||
|
|
||||||
if (!Enabled.Value)
|
if (!Enabled.Value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@@ -63,9 +64,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected virtual void UpdateActiveState()
|
protected virtual void UpdateActiveState()
|
||||||
{
|
{
|
||||||
DarkerColour = Active.Value ? ColourProvider.Highlight1 : ColourProvider.Background3;
|
DarkerColour = Active.Value ? ColourProvider?.Highlight1 ?? Colour4.Gray : ColourProvider?.Background3 ?? Colour4.DimGray;
|
||||||
LighterColour = Active.Value ? ColourProvider.Colour0 : ColourProvider.Background1;
|
LighterColour = Active.Value ? ColourProvider?.Colour0 ?? Colour4.AliceBlue : ColourProvider?.Background1 ?? Colour4.LightGray;
|
||||||
TextColour = Active.Value ? ColourProvider.Background6 : ColourProvider.Content1;
|
TextColour = Active.Value ? ColourProvider?.Background6 ?? Colour4.Black : ColourProvider?.Content1 ?? Colour4.DarkGray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playSample()
|
private void playSample()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace osu.Game.Online.Chat
|
|||||||
// http[s]://<domain>.<tld>[:port][/path][?query][#fragment]
|
// http[s]://<domain>.<tld>[:port][/path][?query][#fragment]
|
||||||
private static readonly Regex advanced_link_regex = new Regex(
|
private static readonly Regex advanced_link_regex = new Regex(
|
||||||
// protocol
|
// protocol
|
||||||
@"(?<link>(https?|osu(mp)?):\/\/" +
|
@"(?<link>(https?|jvnkosu(mp)?):\/\/" +
|
||||||
// domain + tld
|
// domain + tld
|
||||||
@"(?<domain>(?:[a-z0-9]\.|[a-z0-9][a-z0-9-]*[a-z0-9]\.)*[a-z0-9-]*[a-z0-9]" +
|
@"(?<domain>(?:[a-z0-9]\.|[a-z0-9][a-z0-9-]*[a-z0-9]\.)*[a-z0-9-]*[a-z0-9]" +
|
||||||
// port (optional)
|
// port (optional)
|
||||||
@@ -60,7 +60,7 @@ namespace osu.Game.Online.Chat
|
|||||||
.Split('/').Last(); // only keep domain name, ignoring protocol.
|
.Split('/').Last(); // only keep domain name, ignoring protocol.
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string websiteRootUrl = "osu.ppy.sh";
|
private static string websiteRootUrl = "osu.jvnko.boats";
|
||||||
|
|
||||||
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[]? escapeChars = null)
|
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[]? escapeChars = null)
|
||||||
{
|
{
|
||||||
@@ -211,7 +211,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case @"osu":
|
case @"jvnkosu":
|
||||||
// every internal link also needs some kind of argument
|
// every internal link also needs some kind of argument
|
||||||
if (args.Length < 3)
|
if (args.Length < 3)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request to leave the currently joined room.
|
/// Request to leave the currently joined room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="NotJoinedRoomException">If the user is not in a room.</exception>
|
|
||||||
Task LeaveRoom();
|
Task LeaveRoom();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -319,9 +319,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
public Task LeaveRoom()
|
public Task LeaveRoom()
|
||||||
{
|
{
|
||||||
if (Room == null)
|
|
||||||
return Task.CompletedTask;
|
|
||||||
|
|
||||||
// The join may have not completed yet, so certain tasks that either update the room or reference the room should be cancelled.
|
// The join may have not completed yet, so certain tasks that either update the room or reference the room should be cancelled.
|
||||||
// This includes the setting of Room itself along with the initial update of the room settings on join.
|
// This includes the setting of Room itself along with the initial update of the room settings on join.
|
||||||
joinCancellationSource?.Cancel();
|
joinCancellationSource?.Cancel();
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace osu.Game
|
|||||||
public const string GAME_NAME = "jvnkosu!";
|
public const string GAME_NAME = "jvnkosu!";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public const string OSU_PROTOCOL = "jnvkosu://";
|
public const string OSU_PROTOCOL = "jvnkosu://";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The filename of the main client database.
|
/// The filename of the main client database.
|
||||||
|
|||||||
@@ -33,7 +33,27 @@ namespace osu.Game.Overlays.Chat
|
|||||||
{
|
{
|
||||||
var request = new ChatReportRequest(message.Id, reason, comments);
|
var request = new ChatReportRequest(message.Id, reason, comments);
|
||||||
|
|
||||||
request.Success += () => channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(UsersStrings.ReportThanks.ToString()));
|
request.Success += () =>
|
||||||
|
{
|
||||||
|
string thanksMessage;
|
||||||
|
|
||||||
|
switch (channelManager.CurrentChannel.Value.Type)
|
||||||
|
{
|
||||||
|
case ChannelType.PM:
|
||||||
|
thanksMessage = """
|
||||||
|
Chat moderators have been alerted. You have reported a private message so they will not be able to read history to maintain your privacy. Please make sure to include as much details as you can.
|
||||||
|
You can submit a second report with more details if required, or contact abuse@ppy.sh if a user is being extremely offensive.
|
||||||
|
You can also block a user via the block button on their user profile, or by right-clicking on their name in the chat and selecting "Block".
|
||||||
|
""";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
thanksMessage = @"Chat moderators have been alerted. Thanks for your help.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(thanksMessage));
|
||||||
|
};
|
||||||
|
|
||||||
api.Queue(request);
|
api.Queue(request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,15 @@ namespace osu.Game.Overlays
|
|||||||
audio.Samples.AddAdjustment(AdjustableProperty.Volume, audioVolume);
|
audio.Samples.AddAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected void RemoveAudioAdjustments()
|
||||||
{
|
{
|
||||||
audio?.Tracks.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
|
audio?.Tracks.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||||
audio?.Samples.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
|
audio?.Samples.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
RemoveAudioAdjustments();
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected override void UpdateActiveState()
|
protected override void UpdateActiveState()
|
||||||
{
|
{
|
||||||
DarkerColour = Active.Value ? colours.Orange1 : ColourProvider.Background3;
|
DarkerColour = Active.Value ? colours.Orange1 : ColourProvider?.Background3 ?? Colour4.DarkGray;
|
||||||
LighterColour = Active.Value ? colours.Orange0 : ColourProvider.Background1;
|
LighterColour = Active.Value ? colours.Orange0 : ColourProvider?.Background1 ?? Colour4.LightGray;
|
||||||
TextColour = Active.Value ? ColourProvider.Background6 : ColourProvider.Content1;
|
TextColour = Active.Value ? ColourProvider?.Background6 ?? Colour4.Black : ColourProvider?.Content1 ?? Colour4.Gray;
|
||||||
|
|
||||||
if (Active.Value)
|
if (Active.Value)
|
||||||
this.ShowPopover();
|
this.ShowPopover();
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
private void onSeek(double progress)
|
private void onSeek(double progress)
|
||||||
{
|
{
|
||||||
if (lastSeekTime == null || Time.Current - lastSeekTime > TRACK_DRAG_SEEK_DEBOUNCE)
|
if (!musicController.IsPlaying || lastSeekTime == null || Time.Current - lastSeekTime > TRACK_DRAG_SEEK_DEBOUNCE)
|
||||||
{
|
{
|
||||||
musicController.SeekTo(progress);
|
musicController.SeekTo(progress);
|
||||||
lastSeekTime = Time.Current;
|
lastSeekTime = Time.Current;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
case RankingsScope.Performance:
|
case RankingsScope.Performance:
|
||||||
case RankingsScope.Score:
|
case RankingsScope.Score:
|
||||||
case RankingsScope.Country:
|
case RankingsScope.Country:
|
||||||
case RankingsScope.Spotlights:
|
case RankingsScope.Playlists:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCountry))]
|
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCountry))]
|
||||||
Country,
|
Country,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCharts))]
|
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypePlaylists))]
|
||||||
Spotlights,
|
Playlists,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeKudosu))]
|
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeKudosu))]
|
||||||
Kudosu,
|
Kudosu,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
ruleset.BindValueChanged(_ =>
|
ruleset.BindValueChanged(_ =>
|
||||||
{
|
{
|
||||||
if (Header.Current.Value == RankingsScope.Spotlights)
|
if (Header.Current.Value == RankingsScope.Playlists)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scheduler.AddOnce(triggerTabChanged);
|
Scheduler.AddOnce(triggerTabChanged);
|
||||||
@@ -99,7 +99,7 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
lastRequest?.Cancel();
|
lastRequest?.Cancel();
|
||||||
|
|
||||||
if (Header.Current.Value == RankingsScope.Spotlights)
|
if (Header.Current.Value == RankingsScope.Playlists)
|
||||||
{
|
{
|
||||||
LoadDisplay(new SpotlightsLayout
|
LoadDisplay(new SpotlightsLayout
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using osu.Framework.Input.Handlers.Tablet;
|
|||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@@ -34,6 +35,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
|
|
||||||
private readonly Bindable<Vector2> areaOffset = new Bindable<Vector2>();
|
private readonly Bindable<Vector2> areaOffset = new Bindable<Vector2>();
|
||||||
private readonly Bindable<Vector2> areaSize = new Bindable<Vector2>();
|
private readonly Bindable<Vector2> areaSize = new Bindable<Vector2>();
|
||||||
|
private readonly Bindable<Vector2> outputAreaSize = new Bindable<Vector2>();
|
||||||
|
private readonly Bindable<Vector2> outputAreaOffset = new Bindable<Vector2>();
|
||||||
private readonly IBindable<TabletInfo> tablet = new Bindable<TabletInfo>();
|
private readonly IBindable<TabletInfo> tablet = new Bindable<TabletInfo>();
|
||||||
|
|
||||||
private readonly BindableNumber<float> offsetX = new BindableNumber<float> { MinValue = 0, Precision = 1 };
|
private readonly BindableNumber<float> offsetX = new BindableNumber<float> { MinValue = 0, Precision = 1 };
|
||||||
@@ -46,6 +49,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
|
|
||||||
private readonly BindableNumber<float> pressureThreshold = new BindableNumber<float> { MinValue = 0.0f, MaxValue = 1.0f, Precision = 0.005f };
|
private readonly BindableNumber<float> pressureThreshold = new BindableNumber<float> { MinValue = 0.0f, MaxValue = 1.0f, Precision = 0.005f };
|
||||||
|
|
||||||
|
private Bindable<ScalingMode> scalingMode = null!;
|
||||||
|
private Bindable<float> scalingSizeX = null!;
|
||||||
|
private Bindable<float> scalingSizeY = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
@@ -77,8 +84,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours, LocalisationManager localisation)
|
private void load(OsuColour colours, LocalisationManager localisation, OsuConfigManager osuConfig)
|
||||||
{
|
{
|
||||||
|
scalingMode = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling);
|
||||||
|
scalingSizeX = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeX);
|
||||||
|
scalingSizeY = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeY);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
@@ -152,7 +163,16 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Text = TabletSettingsStrings.ConformToCurrentGameAspectRatio,
|
Text = TabletSettingsStrings.ConformToCurrentGameAspectRatio,
|
||||||
Action = () =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
forceAspectRatio((float)host.Window.ClientSize.Width / host.Window.ClientSize.Height);
|
float gameplayWidth = host.Window.ClientSize.Width;
|
||||||
|
float gameplayHeight = host.Window.ClientSize.Height;
|
||||||
|
|
||||||
|
if (scalingMode.Value == ScalingMode.Everything)
|
||||||
|
{
|
||||||
|
gameplayWidth *= scalingSizeX.Value;
|
||||||
|
gameplayHeight *= scalingSizeY.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
forceAspectRatio(gameplayWidth / gameplayHeight);
|
||||||
},
|
},
|
||||||
CanBeShown = { BindTarget = enabled }
|
CanBeShown = { BindTarget = enabled }
|
||||||
},
|
},
|
||||||
@@ -249,6 +269,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
sizeY.Value = val.NewValue.Y;
|
sizeY.Value = val.NewValue.Y;
|
||||||
}), true);
|
}), true);
|
||||||
|
|
||||||
|
outputAreaSize.BindTo(tabletHandler.OutputAreaSize);
|
||||||
|
outputAreaOffset.BindTo(tabletHandler.OutputAreaOffset);
|
||||||
|
|
||||||
sizeX.BindValueChanged(val =>
|
sizeX.BindValueChanged(val =>
|
||||||
{
|
{
|
||||||
areaSize.Value = new Vector2(val.NewValue, areaSize.Value.Y);
|
areaSize.Value = new Vector2(val.NewValue, areaSize.Value.Y);
|
||||||
|
|||||||
@@ -1,7 +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.
|
||||||
|
|
||||||
#nullable disable
|
#nullable enable
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@@ -19,19 +19,22 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
{
|
{
|
||||||
protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader;
|
protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader;
|
||||||
|
|
||||||
[Resolved]
|
// TODO: refactor seasonal bg code to the way it was before options were introduced
|
||||||
private SeasonalBackgroundLoader backgroundLoader { get; set; }
|
private SeasonalBackgroundLoader? backgroundLoader = null!;
|
||||||
|
|
||||||
private IBindable<APIUser> user;
|
private IBindable<APIUser> user = null!;
|
||||||
|
|
||||||
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
|
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown = null!;
|
||||||
|
|
||||||
private Bindable<bool> useSeasonalBackgrounds;
|
private Bindable<bool> useSeasonalBackgrounds = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, IAPIProvider api)
|
private void load(OsuConfigManager config, IAPIProvider api, SeasonalBackgroundLoader? backgroundLoader)
|
||||||
{
|
{
|
||||||
user = api.LocalUser.GetBoundCopy();
|
user = api.LocalUser.GetBoundCopy();
|
||||||
|
|
||||||
|
this.backgroundLoader = backgroundLoader;
|
||||||
|
|
||||||
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
|
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
|
||||||
|
|
||||||
var backgroundToggle = new SettingsCheckbox
|
var backgroundToggle = new SettingsCheckbox
|
||||||
@@ -50,17 +53,17 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
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)
|
// TODO: the category dropdown disappear if no backgrounds (e.g. when first enabling the setting)
|
||||||
refreshButton.CanBeShown.BindTo(useSeasonalBackgrounds);
|
refreshButton.CanBeShown.BindTo(useSeasonalBackgrounds);
|
||||||
categoryDropdown.CanBeShown.BindTo(useSeasonalBackgrounds);
|
categoryDropdown.CanBeShown.BindTo(useSeasonalBackgrounds);
|
||||||
useSeasonalBackgrounds.BindValueChanged(
|
useSeasonalBackgrounds.BindValueChanged(
|
||||||
_ => backgroundLoader.RefreshCategories(true)
|
_ => backgroundLoader?.RefreshCategories(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
backgroundLoader.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
|
backgroundLoader?.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -529,6 +529,8 @@ namespace osu.Game.Overlays.SkinEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
SelectedComponents.Add(component);
|
SelectedComponents.Add(component);
|
||||||
|
|
||||||
|
if (!component.UsesFixedAnchor)
|
||||||
SkinSelectionHandler.ApplyClosestAnchorOrigin(drawableComponent);
|
SkinSelectionHandler.ApplyClosestAnchorOrigin(drawableComponent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,8 @@ namespace osu.Game.Overlays.Volume
|
|||||||
|
|
||||||
private float dragDelta;
|
private float dragDelta;
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e) => true; // handle to prevent drawables behind from potentially receiving the mouse down
|
||||||
|
|
||||||
protected override bool OnDragStart(DragStartEvent e)
|
protected override bool OnDragStart(DragStartEvent e)
|
||||||
{
|
{
|
||||||
dragDelta = 0;
|
dragDelta = 0;
|
||||||
|
|||||||
@@ -1,47 +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 osu.Framework.Audio;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Overlays.Settings;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
|
||||||
{
|
|
||||||
public abstract class ModRateAdjustConcrete : ModRateAdjust
|
|
||||||
{
|
|
||||||
public override string Name => "Rate Adjust";
|
|
||||||
public override LocalisableString Description => "[DEBUG BUILDS ONLY] Set any speed";
|
|
||||||
public override string Acronym => "_R";
|
|
||||||
private readonly RateAdjustModHelper rateAdjustHelper;
|
|
||||||
|
|
||||||
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
|
||||||
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
|
||||||
{
|
|
||||||
MinValue = 0.1, // BASS breaks at lower rates
|
|
||||||
MaxValue = 10,
|
|
||||||
Precision = 0.01
|
|
||||||
};
|
|
||||||
|
|
||||||
[SettingSource("Adjust pitch", "Should pitch be adjusted with speed")]
|
|
||||||
public virtual BindableBool AdjustPitch { get; } = new BindableBool();
|
|
||||||
|
|
||||||
|
|
||||||
protected ModRateAdjustConcrete()
|
|
||||||
{
|
|
||||||
rateAdjustHelper = new RateAdjustModHelper(SpeedChange);
|
|
||||||
rateAdjustHelper.HandleAudioAdjustments(AdjustPitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
public override void ApplyToTrack(IAdjustableAudioComponent track)
|
|
||||||
{
|
|
||||||
rateAdjustHelper.ApplyToTrack(track);
|
|
||||||
}
|
|
||||||
public override bool Ranked => false;
|
|
||||||
public override ModType Type => ModType.Special;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,12 +13,14 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Storyboards.Drawables;
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Backgrounds
|
namespace osu.Game.Screens.Backgrounds
|
||||||
{
|
{
|
||||||
public partial class EditorBackgroundScreen : BackgroundScreen
|
public partial class EditorBackgroundScreen : BackgroundScreen
|
||||||
{
|
{
|
||||||
|
private readonly EditorBeatmap editorBeatmap;
|
||||||
private readonly Container dimContainer;
|
private readonly Container dimContainer;
|
||||||
|
|
||||||
private CancellationTokenSource? cancellationTokenSource;
|
private CancellationTokenSource? cancellationTokenSource;
|
||||||
@@ -36,8 +38,9 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
||||||
|
|
||||||
public EditorBackgroundScreen()
|
public EditorBackgroundScreen(EditorBeatmap editorBeatmap)
|
||||||
{
|
{
|
||||||
|
this.editorBeatmap = editorBeatmap;
|
||||||
InternalChild = dimContainer = new Container
|
InternalChild = dimContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@@ -58,10 +61,11 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
private IEnumerable<Drawable> createContent() =>
|
private IEnumerable<Drawable> createContent() =>
|
||||||
[
|
[
|
||||||
new BeatmapBackground(beatmap.Value) { RelativeSizeAxes = Axes.Both, },
|
new BeatmapBackground(beatmap.Value) { RelativeSizeAxes = Axes.Both, },
|
||||||
// this kooky container nesting is here because the storyboard needs a custom clock
|
// one reason for this kooky container nesting being here is that the storyboard needs a custom clock
|
||||||
// but also needs it on an isolated-enough level that doesn't break screen stack expiry logic (which happens if the clock was put on `this`),
|
// but also needs it on an isolated-enough level that doesn't break screen stack expiry logic (which happens if the clock was put on `this`),
|
||||||
// or doesn't make it literally impossible to fade the storyboard in/out in real time (which happens if the fade transforms were to be applied directly to the storyboard).
|
// or doesn't make it literally impossible to fade the storyboard in/out in real time (which happens if the fade transforms were to be applied directly to the storyboard).
|
||||||
new Container
|
// another is that we need `EditorSkinProvidingContainer` so that storyboard sample lookups succeed.
|
||||||
|
new EditorSkinProvidingContainer(editorBeatmap)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = new DrawableStoryboard(beatmap.Value.Storyboard)
|
Child = new DrawableStoryboard(beatmap.Value.Storyboard)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
|||||||
double seekDestination = markerPos / DrawWidth * editorClock.TrackLength;
|
double seekDestination = markerPos / DrawWidth * editorClock.TrackLength;
|
||||||
marker.X = (float)seekDestination;
|
marker.X = (float)seekDestination;
|
||||||
|
|
||||||
if (!instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE)
|
if (editorClock.IsRunning && !instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
editorClock.SeekSmoothlyTo(seekDestination);
|
editorClock.SeekSmoothlyTo(seekDestination);
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private MusicController musicController { get; set; }
|
private MusicController musicController { get; set; }
|
||||||
|
|
||||||
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen();
|
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen(editorBeatmap);
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -169,6 +169,20 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
|||||||
{
|
{
|
||||||
Text = "Searching for opponents...";
|
Text = "Searching for opponents...";
|
||||||
|
|
||||||
|
Activated = () =>
|
||||||
|
{
|
||||||
|
performer?.PerformFromScreen(s =>
|
||||||
|
{
|
||||||
|
if (s is ScreenIntro || s is ScreenQueue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s.Push(new ScreenIntro());
|
||||||
|
}, [typeof(ScreenIntro), typeof(ScreenQueue)]);
|
||||||
|
|
||||||
|
// Closed when appropriate by SearchInForeground().
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
CompletionClickAction = () =>
|
CompletionClickAction = () =>
|
||||||
{
|
{
|
||||||
client.MatchmakingAcceptInvitation().FireAndForget();
|
client.MatchmakingAcceptInvitation().FireAndForget();
|
||||||
|
|||||||
@@ -354,37 +354,9 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MatchmakingScreenState.PendingAccept:
|
case MatchmakingScreenState.PendingAccept:
|
||||||
mainContent.Child = new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(20),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Text = "Found a match!",
|
|
||||||
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Regular, typeface: Typeface.TorusAlternate),
|
|
||||||
},
|
|
||||||
new SelectionButton(200)
|
|
||||||
{
|
|
||||||
DarkerColour = colours.YellowDark,
|
|
||||||
LighterColour = colours.YellowLight,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Action = () =>
|
|
||||||
{
|
|
||||||
client.MatchmakingAcceptInvitation().FireAndForget();
|
client.MatchmakingAcceptInvitation().FireAndForget();
|
||||||
SetState(MatchmakingScreenState.AcceptedWaitingForRoom);
|
SetState(MatchmakingScreenState.AcceptedWaitingForRoom);
|
||||||
},
|
|
||||||
Text = "Join match!",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
matchFoundSample?.Play();
|
matchFoundSample?.Play();
|
||||||
musicController.DuckMomentarily(1250);
|
musicController.DuckMomentarily(1250);
|
||||||
break;
|
break;
|
||||||
@@ -403,7 +375,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Text = "Waiting for all players...",
|
Text = "Waiting for opponents...",
|
||||||
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Light, typeface: Typeface.TorusAlternate),
|
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Light, typeface: Typeface.TorusAlternate),
|
||||||
},
|
},
|
||||||
new LoadingSpinner
|
new LoadingSpinner
|
||||||
|
|||||||
@@ -90,6 +90,15 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
client.ChangeState(MultiplayerUserState.Idle).FireAndForget();
|
client.ChangeState(MultiplayerUserState.Idle).FireAndForget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool OnExiting(ScreenExitEvent e)
|
||||||
|
{
|
||||||
|
if (base.OnExiting(e))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
client.LeaveRoom().FireAndForget();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected override string ScreenTitle => "Multiplayer";
|
protected override string ScreenTitle => "Multiplayer";
|
||||||
|
|
||||||
protected override LoungeSubScreen CreateLounge() => new MultiplayerLoungeSubScreen();
|
protected override LoungeSubScreen CreateLounge() => new MultiplayerLoungeSubScreen();
|
||||||
|
|||||||
@@ -42,10 +42,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override OsuClickableContainer CreateButton() => skipButton = new Button
|
protected override OsuClickableContainer CreateButton(IBindable<bool> inSkipPeriod) => skipButton = new Button
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
InSkipPeriod = { BindTarget = inSkipPeriod },
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@@ -119,6 +120,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
public readonly BindableInt SkippedCount = new BindableInt();
|
public readonly BindableInt SkippedCount = new BindableInt();
|
||||||
public readonly BindableInt RequiredCount = new BindableInt();
|
public readonly BindableInt RequiredCount = new BindableInt();
|
||||||
|
public readonly BindableBool InSkipPeriod = new BindableBool();
|
||||||
|
|
||||||
|
private readonly BindableBool clicked = new BindableBool();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; } = null!;
|
private OsuColour colours { get; set; } = null!;
|
||||||
@@ -201,11 +205,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
SkippedCount.BindValueChanged(_ => updateCount());
|
SkippedCount.BindValueChanged(_ => updateCount());
|
||||||
RequiredCount.BindValueChanged(_ => updateCount(), true);
|
RequiredCount.BindValueChanged(_ => updateCount(), true);
|
||||||
|
|
||||||
|
InSkipPeriod.BindValueChanged(_ => updateEnabledState());
|
||||||
|
clicked.BindValueChanged(_ => updateEnabledState(), true);
|
||||||
|
|
||||||
Enabled.BindValueChanged(_ => updateColours(), true);
|
Enabled.BindValueChanged(_ => updateColours(), true);
|
||||||
|
|
||||||
FinishTransforms(true);
|
FinishTransforms(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateEnabledState() => Enabled.Value = InSkipPeriod.Value && !clicked.Value;
|
||||||
|
|
||||||
private void updateChevronsSpacing()
|
private void updateChevronsSpacing()
|
||||||
{
|
{
|
||||||
if (SkippedCount.Value > 0 && RequiredCount.Value > 1)
|
if (SkippedCount.Value > 0 && RequiredCount.Value > 1)
|
||||||
@@ -300,7 +310,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
base.OnClick(e);
|
base.OnClick(e);
|
||||||
|
|
||||||
Enabled.Value = false;
|
clicked.Value = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
public partial class FailOverlay : GameplayMenuOverlay
|
public partial class FailOverlay : GameplayMenuOverlay
|
||||||
{
|
{
|
||||||
public Func<Task<ScoreInfo>>? SaveReplay;
|
public Func<Task<ScoreInfo>>? SaveReplay { get; init; }
|
||||||
|
|
||||||
public override LocalisableString Header => GameplayMenuOverlayStrings.FailedHeader;
|
public override LocalisableString Header => GameplayMenuOverlayStrings.FailedHeader;
|
||||||
|
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
else if (Tracked)
|
else if (Tracked)
|
||||||
{
|
{
|
||||||
widthExtension = true;
|
widthExtension = true;
|
||||||
setTrackedPanelColour(BackgroundColour);
|
setPanelColour(BackgroundColour ?? colours.Orange2);
|
||||||
}
|
}
|
||||||
else if (isFriend)
|
else if (isFriend)
|
||||||
{
|
{
|
||||||
@@ -380,13 +380,6 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
scorePanel.BorderColour = ColourInfo.GradientVertical(baseColour.Opacity(0.2f), baseColour);
|
scorePanel.BorderColour = ColourInfo.GradientVertical(baseColour.Opacity(0.2f), baseColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTrackedPanelColour(Color4? backgroundColour)
|
|
||||||
{
|
|
||||||
leftLayerGradient.Colour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue2).Opacity(0.3f), backgroundColour ?? colours.Blue2);
|
|
||||||
rightLayerGradient.Colour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue4).Opacity(0.25f), (backgroundColour ?? colours.Blue3).Opacity(0.6f));
|
|
||||||
scorePanel.BorderColour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue1).Opacity(0.2f), backgroundColour ?? colours.Blue1);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|||||||
@@ -27,5 +27,14 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
AbortConfirm();
|
AbortConfirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Confirm()
|
||||||
|
{
|
||||||
|
base.Confirm();
|
||||||
|
|
||||||
|
// Not removing immediately can lead to delays due to async disposal.
|
||||||
|
// This is done here rather than in `Player` because it's simpler to handle.
|
||||||
|
RemoveAudioAdjustments();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,14 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
AbortConfirm();
|
AbortConfirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Confirm()
|
||||||
|
{
|
||||||
|
base.Confirm();
|
||||||
|
|
||||||
|
// Not removing immediately can lead to delays due to async disposal.
|
||||||
|
// This is done here rather than in `Player` because it's simpler to handle.
|
||||||
|
RemoveAudioAdjustments();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ namespace osu.Game.Screens.Play
|
|||||||
},
|
},
|
||||||
FailOverlay = new FailOverlay
|
FailOverlay = new FailOverlay
|
||||||
{
|
{
|
||||||
SaveReplay = async () => await prepareAndImportScoreAsync(true).ConfigureAwait(false),
|
SaveReplay = Configuration.AllowUserInteraction ? async () => await prepareAndImportScoreAsync(true).ConfigureAwait(false) : null,
|
||||||
OnRetry = Configuration.AllowUserInteraction ? () => Restart() : null,
|
OnRetry = Configuration.AllowUserInteraction ? () => Restart() : null,
|
||||||
OnQuit = () => PerformExitWithConfirmation(),
|
OnQuit = () => PerformExitWithConfirmation(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Screens.Play.PlayerSettings;
|
using osu.Game.Screens.Play.PlayerSettings;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@@ -100,7 +101,9 @@ namespace osu.Game.Screens.Play
|
|||||||
playbackSettings.UserPlaybackRate.BindTo(master.UserPlaybackRate);
|
playbackSettings.UserPlaybackRate.BindTo(master.UserPlaybackRate);
|
||||||
|
|
||||||
HUDOverlay.PlayerSettingsOverlay.AddAtStart(playbackSettings);
|
HUDOverlay.PlayerSettingsOverlay.AddAtStart(playbackSettings);
|
||||||
AddInternal(failIndicator = new ReplayFailIndicator(GameplayClockContainer)
|
AddInternal(new RulesetSkinProvidingContainer(GameplayState.Ruleset, GameplayState.Beatmap, Beatmap.Value.Skin)
|
||||||
|
{
|
||||||
|
Child = failIndicator = new ReplayFailIndicator(GameplayClockContainer)
|
||||||
{
|
{
|
||||||
GoToResults = () =>
|
GoToResults = () =>
|
||||||
{
|
{
|
||||||
@@ -110,6 +113,7 @@ namespace osu.Game.Screens.Play
|
|||||||
ValidForResume = false;
|
ValidForResume = false;
|
||||||
this.Push(new SoloResultsScreen(Score.ScoreInfo));
|
this.Push(new SoloResultsScreen(Score.ScoreInfo));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,17 @@ namespace osu.Game.Screens.Play
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (importFailedScore != null)
|
||||||
|
{
|
||||||
button.TooltipText = @"save score";
|
button.TooltipText = @"save score";
|
||||||
button.Enabled.Value = true;
|
button.Enabled.Value = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button.TooltipText = @"replay unavailable";
|
||||||
|
button.Enabled.Value = false;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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;
|
||||||
@@ -52,9 +53,9 @@ namespace osu.Game.Screens.Play
|
|||||||
private double displayTime;
|
private double displayTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Becomes <see langword="false"/> when the overlay starts fading out.
|
/// Whether the gameplay clock is currently at the skippable period.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool isClickable;
|
private readonly BindableBool inSkipPeriod = new BindableBool();
|
||||||
|
|
||||||
private bool skipQueued;
|
private bool skipQueued;
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ namespace osu.Game.Screens.Play
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
button = CreateButton(),
|
button = CreateButton(inSkipPeriod),
|
||||||
RemainingTimeBox = new Circle
|
RemainingTimeBox = new Circle
|
||||||
{
|
{
|
||||||
Height = 5,
|
Height = 5,
|
||||||
@@ -106,10 +107,15 @@ namespace osu.Game.Screens.Play
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual OsuClickableContainer CreateButton() => new Button
|
/// <summary>
|
||||||
|
/// Creates a skip button.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inSkipPeriod">Whether the gameplay clock is currently at the skippable period.</param>
|
||||||
|
protected virtual OsuClickableContainer CreateButton(IBindable<bool> inSkipPeriod) => new Button
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
Enabled = { BindTarget = inSkipPeriod },
|
||||||
};
|
};
|
||||||
|
|
||||||
private const double fade_time = 300;
|
private const double fade_time = 300;
|
||||||
@@ -187,17 +193,13 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
RemainingTimeBox.Width = (float)Interpolation.Lerp(RemainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
|
RemainingTimeBox.Width = (float)Interpolation.Lerp(RemainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
|
||||||
|
|
||||||
isClickable = progress > 0;
|
inSkipPeriod.Value = progress > 0;
|
||||||
|
buttonContainer.State.Value = inSkipPeriod.Value ? Visibility.Visible : Visibility.Hidden;
|
||||||
if (!isClickable)
|
|
||||||
button.Enabled.Value = false;
|
|
||||||
|
|
||||||
buttonContainer.State.Value = isClickable ? Visibility.Visible : Visibility.Hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||||
{
|
{
|
||||||
if (isClickable && !e.HasAnyButtonPressed)
|
if (inSkipPeriod.Value && !e.HasAnyButtonPressed)
|
||||||
FadingContent.TriggerShow();
|
FadingContent.TriggerShow();
|
||||||
|
|
||||||
return base.OnMouseMove(e);
|
return base.OnMouseMove(e);
|
||||||
|
|||||||
@@ -407,14 +407,26 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
private LeaderboardState displayedState;
|
private LeaderboardState displayedState;
|
||||||
|
|
||||||
|
private ScheduledDelegate? loadingShowDelegate;
|
||||||
|
|
||||||
protected void SetState(LeaderboardState state)
|
protected void SetState(LeaderboardState state)
|
||||||
{
|
{
|
||||||
if (state == displayedState)
|
if (state == displayedState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (state == LeaderboardState.Retrieving)
|
if (state == LeaderboardState.Retrieving)
|
||||||
loading.Show();
|
{
|
||||||
|
// Slight delay so this doesn't display for a few silly frames for local score retrievals.
|
||||||
|
loadingShowDelegate ??= Scheduler.AddDelayed(() => loading.Show(), 200);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
loadingShowDelegate?.Cancel();
|
||||||
|
loadingShowDelegate = null;
|
||||||
|
|
||||||
|
loading.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
loading.Hide();
|
loading.Hide();
|
||||||
|
|
||||||
displayedState = state;
|
displayedState = state;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
{
|
{
|
||||||
perf = (float)Math.Round((float?)d.NewValue.PerformanceAttributes?.Total ?? 0f, 1); // yikes
|
perf = (float)Math.Round((float?)d.NewValue.PerformanceAttributes?.Total ?? 0f, 1); // yikes
|
||||||
var arr = difficultyStatisticsDisplay.Statistics.ToArray();
|
var arr = difficultyStatisticsDisplay.Statistics.ToArray();
|
||||||
arr[0] = new StatisticDifficulty.Data("Max PP", perf, perf, perf);
|
if (arr.Length >= 1) arr[0] = new StatisticDifficulty.Data("Max PP", perf, perf, perf);
|
||||||
difficultyStatisticsDisplay.Statistics = arr.AsEnumerable();
|
difficultyStatisticsDisplay.Statistics = arr.AsEnumerable();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
if (spectatorList != null)
|
if (spectatorList != null)
|
||||||
spectatorList.Position = pos;
|
spectatorList.Position = pos;
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@@ -238,6 +241,9 @@ namespace osu.Game.Skinning
|
|||||||
keyCounter.Position = new Vector2(-(hitError.Width + padding), -(padding * 2 + song_progress_offset_height));
|
keyCounter.Position = new Vector2(-(hitError.Width + padding), -(padding * 2 + song_progress_offset_height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|||||||
44
osu.Game/Skinning/LegacyPerformancePointsCounter.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public partial class LegacyPerformancePointsCounter : PerformancePointsCounter, ISerialisableDrawable
|
||||||
|
{
|
||||||
|
protected override double RollingDuration => 1000;
|
||||||
|
protected override Easing RollingEasing => Easing.Out;
|
||||||
|
|
||||||
|
private const float alpha_when_invalid = 0.3f;
|
||||||
|
|
||||||
|
public LegacyPerformancePointsCounter()
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight;
|
||||||
|
Origin = Anchor.TopRight;
|
||||||
|
|
||||||
|
Scale = new Vector2(0.96f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsValid
|
||||||
|
{
|
||||||
|
get => base.IsValid;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.IsValid = value;
|
||||||
|
DrawableCount.FadeTo(value ? 1 : alpha_when_invalid, 1000, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override LocalisableString FormatCount(int count) => count.ToString($@"0'{LegacySpriteText.PP_SUFFIX_CHAR}'");
|
||||||
|
|
||||||
|
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -412,6 +412,9 @@ namespace osu.Game.Skinning
|
|||||||
leaderboard.Origin = Anchor.CentreLeft;
|
leaderboard.Origin = Anchor.CentreLeft;
|
||||||
leaderboard.X = 10;
|
leaderboard.X = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
new LegacyDefaultComboCounter(),
|
new LegacyDefaultComboCounter(),
|
||||||
@@ -448,6 +451,9 @@ namespace osu.Game.Skinning
|
|||||||
hitError.Origin = Anchor.CentreLeft;
|
hitError.Origin = Anchor.CentreLeft;
|
||||||
hitError.Rotation = -90;
|
hitError.Rotation = -90;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||||
|
d.UsesFixedAnchor = true;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
|
|||||||