diff --git a/osu.Android.props b/osu.Android.props
index 4198cf2bf4..b2e3b32916 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -51,7 +51,7 @@
-
+
diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs
index b234207848..cd3fb7eb61 100644
--- a/osu.Desktop/OsuGameDesktop.cs
+++ b/osu.Desktop/OsuGameDesktop.cs
@@ -10,14 +10,11 @@ using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Desktop.Security;
-using osu.Desktop.Overlays;
using osu.Framework.Platform;
using osu.Game;
using osu.Desktop.Updater;
using osu.Framework;
using osu.Framework.Logging;
-using osu.Framework.Screens;
-using osu.Game.Screens.Menu;
using osu.Game.Updater;
using osu.Desktop.Windows;
using osu.Framework.Threading;
@@ -27,13 +24,9 @@ namespace osu.Desktop
{
internal class OsuGameDesktop : OsuGame
{
- private readonly bool noVersionOverlay;
- private VersionManager versionManager;
-
public OsuGameDesktop(string[] args = null)
: base(args)
{
- noVersionOverlay = args?.Any(a => a == "--no-version-overlay") ?? false;
}
public override StableStorage GetStorageForStableInstall()
@@ -114,9 +107,6 @@ namespace osu.Desktop
{
base.LoadComplete();
- if (!noVersionOverlay)
- LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
-
LoadComponentAsync(new DiscordRichPresence(), Add);
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
@@ -125,23 +115,6 @@ namespace osu.Desktop
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
}
- protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen)
- {
- base.ScreenChanged(lastScreen, newScreen);
-
- switch (newScreen)
- {
- case IntroScreen _:
- case MainMenu _:
- versionManager?.Show();
- break;
-
- default:
- versionManager?.Hide();
- break;
- }
- }
-
public override void SetHost(GameHost host)
{
base.SetHost(host);
diff --git a/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini b/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
index 36765d61bf..9c987efc60 100644
--- a/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
+++ b/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
@@ -4,11 +4,14 @@ Version: 2.5
[Mania]
Keys: 4
ColumnLineWidth: 3,1,3,1,1
-Hit0: mania/hit0
-Hit50: mania/hit50
-Hit100: mania/hit100
-Hit200: mania/hit200
-Hit300: mania/hit300
-Hit300g: mania/hit300g
+// some skins found in the wild had configuration keys where the @2x suffix was included in the values.
+// the expected compatibility behaviour is that the presence of the @2x suffix shouldn't change anything
+// if @2x assets are present.
+Hit0: mania/hit0@2x
+Hit50: mania/hit50@2x
+Hit100: mania/hit100@2x
+Hit200: mania/hit200@2x
+Hit300: mania/hit300@2x
+Hit300g: mania/hit300g@2x
StageLeft: mania/stage-left
StageRight: mania/stage-right
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
index 75a5495078..d033676ec7 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
@@ -5,8 +5,10 @@ using System;
using System.Linq;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
+using osu.Framework.Testing;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Scoring;
+using osu.Game.Rulesets.Mania.Skinning.Legacy;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@@ -23,15 +25,24 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
if (hitWindows.IsHitResultAllowed(result))
{
- AddStep("Show " + result.GetDescription(), () => SetContents(_ =>
- new DrawableManiaJudgement(new JudgementResult(new HitObject { StartTime = Time.Current }, new Judgement())
- {
- Type = result
- }, null)
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- }));
+ AddStep("Show " + result.GetDescription(), () =>
+ {
+ SetContents(_ =>
+ new DrawableManiaJudgement(new JudgementResult(new HitObject { StartTime = Time.Current }, new Judgement())
+ {
+ Type = result
+ }, null)
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ });
+
+ // for test purposes, undo the Y adjustment related to the `ScorePosition` legacy positioning config value
+ // (see `LegacyManiaJudgementPiece.load()`).
+ // this prevents the judgements showing somewhere below or above the bounding box of the judgement.
+ foreach (var legacyPiece in this.ChildrenOfType())
+ legacyPiece.Y = 0;
+ });
}
}
}
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index a0a179aa7c..5b3abc54d3 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -154,6 +154,8 @@ namespace osu.Game
private MainMenu menuScreen;
+ private VersionManager versionManager;
+
[CanBeNull]
private IntroScreen introScreen;
@@ -746,6 +748,9 @@ namespace osu.Game
ScreenStack.ScreenPushed += screenPushed;
ScreenStack.ScreenExited += screenExited;
+ if (!args?.Any(a => a == @"--no-version-overlay") ?? true)
+ loadComponentSingleFile(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
+
loadComponentSingleFile(osuLogo, logo =>
{
logoContainer.Add(logo);
@@ -1129,10 +1134,16 @@ namespace osu.Game
{
case IntroScreen intro:
introScreen = intro;
+ versionManager?.Show();
break;
case MainMenu menu:
menuScreen = menu;
+ versionManager?.Show();
+ break;
+
+ default:
+ versionManager?.Hide();
break;
}
diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Game/Overlays/VersionManager.cs
similarity index 98%
rename from osu.Desktop/Overlays/VersionManager.cs
rename to osu.Game/Overlays/VersionManager.cs
index e4a3451651..fe6613fba2 100644
--- a/osu.Desktop/Overlays/VersionManager.cs
+++ b/osu.Game/Overlays/VersionManager.cs
@@ -7,13 +7,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-using osu.Game;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
-namespace osu.Desktop.Overlays
+namespace osu.Game.Overlays
{
public class VersionManager : VisibilityContainer
{
diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
index c31239616c..2d5225639f 100644
--- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
@@ -21,6 +21,7 @@ using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Match.Components;
+using osu.Game.Screens.OnlinePlay.Multiplayer;
namespace osu.Game.Screens.OnlinePlay.Match
{
@@ -101,6 +102,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
InternalChildren = new Drawable[]
{
beatmapAvailabilityTracker,
+ new MultiplayerRoomSounds(),
new GridContainer
{
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs
new file mode 100644
index 0000000000..d467a32acb
--- /dev/null
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs
@@ -0,0 +1,65 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Bindables;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Game.Online.Multiplayer;
+
+namespace osu.Game.Screens.OnlinePlay.Multiplayer
+{
+ public class MultiplayerRoomSounds : MultiplayerRoomComposite
+ {
+ private Sample hostChangedSample;
+ private Sample userJoinedSample;
+ private Sample userLeftSample;
+ private Sample userKickedSample;
+
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
+ {
+ hostChangedSample = audio.Samples.Get(@"Multiplayer/host-changed");
+ userJoinedSample = audio.Samples.Get(@"Multiplayer/player-joined");
+ userLeftSample = audio.Samples.Get(@"Multiplayer/player-left");
+ userKickedSample = audio.Samples.Get(@"Multiplayer/player-kicked");
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ Host.BindValueChanged(hostChanged);
+ }
+
+ protected override void UserJoined(MultiplayerRoomUser user)
+ {
+ base.UserJoined(user);
+
+ userJoinedSample?.Play();
+ }
+
+ protected override void UserLeft(MultiplayerRoomUser user)
+ {
+ base.UserLeft(user);
+
+ userLeftSample?.Play();
+ }
+
+ protected override void UserKicked(MultiplayerRoomUser user)
+ {
+ base.UserKicked(user);
+
+ userKickedSample?.Play();
+ }
+
+ private void hostChanged(ValueChangedEvent value)
+ {
+ // only play sound when the host changes from an already-existing host.
+ if (value.OldValue == null) return;
+
+ hostChangedSample?.Play();
+ }
+ }
+}
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
index d36c556fac..fe40a4bfe6 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
@@ -4,12 +4,10 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
-using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
-using osu.Game.Online.Multiplayer;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
@@ -18,10 +16,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
{
private FillFlowContainer panels;
- private Sample userJoinSample;
- private Sample userLeftSample;
- private Sample userKickedSample;
-
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
@@ -41,31 +35,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
}
}
};
-
- userJoinSample = audio.Samples.Get(@"Multiplayer/player-joined");
- userLeftSample = audio.Samples.Get(@"Multiplayer/player-left");
- userKickedSample = audio.Samples.Get(@"Multiplayer/player-kicked");
- }
-
- protected override void UserJoined(MultiplayerRoomUser user)
- {
- base.UserJoined(user);
-
- userJoinSample?.Play();
- }
-
- protected override void UserLeft(MultiplayerRoomUser user)
- {
- base.UserLeft(user);
-
- userLeftSample?.Play();
- }
-
- protected override void UserKicked(MultiplayerRoomUser user)
- {
- base.UserKicked(user);
-
- userKickedSample?.Play();
}
protected override void OnRoomUpdated()
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 81c695b8da..359d9e5624 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -474,13 +474,18 @@ namespace osu.Game.Skinning
{
foreach (string name in getFallbackNames(componentName))
{
+ // some component names (especially user-controlled ones, like `HitX` in mania)
+ // may contain `@2x` scale specifications.
+ // stable happens to check for that and strip them, so do the same to match stable behaviour.
+ string lookupName = name.Replace(@"@2x", string.Empty);
+
float ratio = 2;
- var texture = Textures?.Get($"{name}@2x", wrapModeS, wrapModeT);
+ var texture = Textures?.Get(@$"{lookupName}@2x", wrapModeS, wrapModeT);
if (texture == null)
{
ratio = 1;
- texture = Textures?.Get(name, wrapModeS, wrapModeT);
+ texture = Textures?.Get(lookupName, wrapModeS, wrapModeT);
}
if (texture == null)
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 2609f17c73..2e5c9f4548 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -37,7 +37,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 0064a597fd..897be33c18 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,7 +61,7 @@
-
+