1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 16:50:21 +08:00

Merge branch 'master' into totp

This commit is contained in:
Dean Herbert
2025-09-18 22:53:20 +09:00
committed by GitHub
Unverified
10 changed files with 85 additions and 53 deletions
@@ -183,6 +183,9 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("Show all judgements", () => counterDisplay.Mode.Value = ArgonJudgementCounterDisplay.DisplayMode.All);
AddWaitStep("wait some", 2);
AddAssert("Check all visible", () => counterDisplay.CounterFlow.ChildrenOfType<ArgonJudgementCounter>().Last().Alpha == 1);
AddToggleStep("toggle wireframe display", t => counterDisplay.WireframeOpacity.Value = t ? 0.3f : 0);
AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = Direction.Vertical);
AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = Direction.Horizontal);
}
private int hiddenCount()
-8
View File
@@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.OnlinePlay.Matchmaking;
using osu.Game.Screens.Play.HUD;
using osu.Game.Skinning;
using osu.Game.Users;
@@ -29,7 +28,6 @@ namespace osu.Game.Configuration
SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null);
SetDefault(Static.LastModSelectPanelSamplePlaybackTime, (double?)null);
SetDefault(Static.LastRankChangeSamplePlaybackTime, (double?)null);
SetDefault(Static.LastMatchmakingCloudSamplePlaybackTime, (double?)null);
SetDefault<APISeasonalBackgrounds?>(Static.SeasonalBackgrounds, null);
SetDefault(Static.TouchInputActive, RuntimeInfo.IsMobile);
SetDefault<ScoreInfo?>(Static.LastLocalUserScore, null);
@@ -83,12 +81,6 @@ namespace osu.Game.Configuration
/// </summary>
LastRankChangeSamplePlaybackTime,
/// <summary>
/// The last playback time in milliseconds for the 'user appear' sample in <see cref="MatchmakingCloud"/>.
/// Used to debounce sample playback to avoid volume saturation from multiple simultaneous playback.
/// </summary>
LastMatchmakingCloudSamplePlaybackTime,
/// <summary>
/// Whether the last positional input received was a touch input.
/// Used in touchscreen detection scenarios (<see cref="TouchInputInterceptor"/>).
@@ -10,7 +10,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens.Ranking;
using osuTK;
@@ -22,6 +21,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
private APIUser[] users = [];
private Container usersContainer = null!;
private readonly Bindable<double?> lastSamplePlayback = new Bindable<double?>();
public APIUser[] Users
{
get => users;
@@ -32,7 +33,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
foreach (var u in usersContainer)
u.Delay(RNG.Next(0, 1000)).FadeOut(500).Expire();
LoadComponentsAsync(users.Select(u => new MovingAvatar(u)), avatars =>
LoadComponentsAsync(users.Select(u => new MovingAvatar(u, lastSamplePlayback)), avatars =>
{
if (usersContainer.Count == 0)
{
@@ -69,24 +70,25 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
private float targetScale;
private float targetAlpha;
private Bindable<double?> lastSamplePlaybackTime = null!;
private readonly Bindable<double?> lastSamplePlayback = new Bindable<double?>();
private const int num_appear_samples = 6;
private Sample? playerAppearSample;
public MovingAvatar(APIUser apiUser)
public MovingAvatar(APIUser apiUser, Bindable<double?> lastSamplePlayback)
: base(apiUser)
{
RelativePositionAxes = Axes.Both;
Scale = new Vector2(2);
Origin = Anchor.Centre;
this.lastSamplePlayback.BindTo(lastSamplePlayback);
}
[BackgroundDependencyLoader]
private void load(AudioManager audio, SessionStatics statics)
private void load(AudioManager audio)
{
playerAppearSample = audio.Samples.Get(@"UI/toolbar-hover");
lastSamplePlaybackTime = statics.GetBindable<double?>(Static.LastMatchmakingCloudSamplePlaybackTime);
playerAppearSample = audio.Samples.Get($@"Multiplayer/Matchmaking/Cloud/appear-{RNG.Next(0, num_appear_samples)}");
}
protected override void LoadComplete()
@@ -103,20 +105,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
Hide();
int appearDelay = RNG.Next(0, 1000);
this.Delay(appearDelay).FadeTo(targetAlpha, 2000, Easing.OutQuint);
Scheduler.AddDelayed(() =>
{
bool enoughTimeElapsed = !lastSamplePlaybackTime.Value.HasValue || Time.Current - lastSamplePlaybackTime.Value >= OsuGameBase.SAMPLE_DEBOUNCE_TIME;
if (!enoughTimeElapsed) return;
var chan = playerAppearSample?.GetChannel();
if (chan == null) return;
chan.Frequency.Value = 1f + RNG.NextDouble(0.25f);
chan.Play();
lastSamplePlaybackTime.Value = Time.Current;
}, appearDelay);
Scheduler.AddDelayed(playAppearSample, appearDelay);
}
private void updateParams()
@@ -128,6 +117,21 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
Scheduler.AddDelayed(updateParams, RNG.Next(500, 5000));
}
private void playAppearSample()
{
bool enoughTimeElapsed = !lastSamplePlayback.Value.HasValue || Time.Current - lastSamplePlayback.Value >= OsuGameBase.SAMPLE_DEBOUNCE_TIME;
if (!enoughTimeElapsed) return;
var chan = playerAppearSample?.GetChannel();
if (chan == null) return;
chan.Frequency.Value = 0.5f + RNG.NextDouble(1.5f);
chan.Balance.Value = MathF.Cos(angle) * OsuGameBase.SFX_STEREO_STRENGTH;
chan.Play();
lastSamplePlayback.Value = Time.Current;
}
protected override void Update()
{
base.Update();
@@ -217,6 +217,10 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
private void updateGameplayState()
{
MultiplayerPlaylistItem item = client.Room!.CurrentPlaylistItem;
if (item.Expired)
return;
RulesetInfo ruleset = rulesets.GetRuleset(item.RulesetID)!;
Ruleset rulesetInstance = ruleset.CreateInstance();
@@ -228,9 +232,15 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
Mods.Value = item.RequiredMods.Select(m => m.ToMod(rulesetInstance)).ToArray();
if (Beatmap.Value is DummyWorkingBeatmap)
client.ChangeState(MultiplayerUserState.Idle).FireAndForget();
{
if (client.LocalUser!.State == MultiplayerUserState.Ready)
client.ChangeState(MultiplayerUserState.Idle).FireAndForget();
}
else
client.ChangeState(MultiplayerUserState.Ready).FireAndForget();
{
if (client.LocalUser!.State == MultiplayerUserState.Idle)
client.ChangeState(MultiplayerUserState.Ready).FireAndForget();
}
client.ChangeBeatmapAvailability(beatmapAvailabilityTracker.Availability.Value).FireAndForget();
}
@@ -45,8 +45,9 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
private bool allowSelection = true;
private readonly Sample[] rouletteSamples = new Sample[8];
private Sample? rouletteResultSample;
private readonly Sample?[] spinSamples = new Sample?[5];
private static readonly int[] spin_sample_sequence = [0, 1, 2, 3, 4, 2, 3, 4];
private Sample? resultSample;
private Sample? swooshSample;
private double? lastSamplePlayback;
@@ -77,15 +78,10 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
rouletteSamples[0] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-0");
rouletteSamples[1] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-1");
rouletteSamples[2] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-2");
rouletteSamples[3] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-3");
rouletteSamples[4] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-4");
rouletteSamples[5] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-2");
rouletteSamples[6] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-3");
rouletteSamples[7] = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-4");
rouletteResultSample = audio.Samples.Get(@"Multiplayer/Matchmaking/roulette-result");
for (int i = 0; i < spinSamples.Length; i++)
spinSamples[i] = audio.Samples.Get($@"Multiplayer/Matchmaking/Selection/roulette-{i}");
resultSample = audio.Samples.Get(@"Multiplayer/Matchmaking/Selection/roulette-result");
swooshSample = audio.Samples.Get(@"SongSelect/options-pop-out");
}
@@ -306,8 +302,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
if (lastSamplePlayback == null || Time.Current - lastSamplePlayback > OsuGameBase.SAMPLE_DEBOUNCE_TIME)
{
int sampleIdx = ii % (rouletteSamples.Length);
rouletteSamples[sampleIdx].Play();
int sequenceIdx = ii % spin_sample_sequence.Length;
spinSamples[spin_sample_sequence[sequenceIdx]]?.Play();
lastSamplePlayback = Time.Current;
}
@@ -338,7 +334,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
panel.MoveTo(Vector2.Zero, 1000, Easing.OutExpo)
.ScaleTo(1.5f, 1000, Easing.OutExpo);
rouletteResultSample?.Play();
resultSample?.Play();
});
}
}
@@ -3,6 +3,8 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
@@ -31,6 +33,9 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
private DateTimeOffset countdownStartTime;
private DateTimeOffset countdownEndTime;
private Sample? stageProgressSample;
private double? lastSamplePlayback;
public StageBubble(MatchmakingStage stage, LocalisableString displayText)
{
this.stage = stage;
@@ -40,7 +45,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
}
[BackgroundDependencyLoader]
private void load()
private void load(AudioManager audio)
{
InternalChild = new CircularContainer
{
@@ -68,6 +73,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
}
}
};
stageProgressSample = audio.Samples.Get(@"Multiplayer/countdown-tick");
}
protected override void LoadComplete()
@@ -98,6 +105,13 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
{
TimeSpan elapsed = DateTimeOffset.Now - countdownStartTime;
progressBar.Width = (float)(elapsed.TotalMilliseconds / duration.TotalMilliseconds);
bool enoughTimeElapsed = lastSamplePlayback == null || Time.Current - lastSamplePlayback >= 1000f;
if (elapsed.TotalMilliseconds < 1000f || !enoughTimeElapsed || elapsed.TotalMilliseconds >= duration.TotalMilliseconds)
return;
stageProgressSample?.Play();
lastSamplePlayback = Time.Current;
}
}
@@ -2,6 +2,8 @@
// 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.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -20,13 +22,16 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
private OsuSpriteText text = null!;
private Sample? textChangedSample;
private double? lastSamplePlayback;
public StageText()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
private void load(AudioManager audio)
{
InternalChild = text = new OsuSpriteText
{
@@ -34,6 +39,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
Font = OsuFont.Default,
AlwaysPresent = true,
};
textChangedSample = audio.Samples.Get(@"Multiplayer/Matchmaking/stage-message");
}
protected override void LoadComplete()
@@ -50,6 +57,12 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
return;
text.Text = getTextForStatus(matchmakingState.Stage);
if (text.Text == string.Empty || (lastSamplePlayback != null && Time.Current - lastSamplePlayback < OsuGameBase.SAMPLE_DEBOUNCE_TIME))
return;
textChangedSample?.Play();
lastSamplePlayback = Time.Current;
});
private LocalisableString getTextForStatus(MatchmakingStage status)
@@ -74,13 +74,13 @@ namespace osu.Game.Screens.Play.HUD
{
wireframesPart = new ArgonCounterSpriteText(wireframesLookup)
{
Anchor = anchor,
Origin = anchor,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
textPart = new ArgonCounterSpriteText(textLookup)
{
Anchor = anchor,
Origin = anchor,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
}
}
@@ -37,7 +37,7 @@ namespace osu.Game.Skinning.Components
Result = result;
AutoSizeAxes = Axes.Both;
AddInternal(textComponent = new ArgonCounterTextComponent(Anchor.TopRight, result.DisplayName.ToUpper()));
AddInternal(textComponent = new ArgonCounterTextComponent(Anchor.TopLeft, result.DisplayName.ToUpper()));
}
private void updateWireframe()
+1 -1
View File
@@ -36,7 +36,7 @@
</PackageReference>
<PackageReference Include="Realm" Version="20.1.0" />
<PackageReference Include="ppy.osu.Framework" Version="2025.908.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2025.911.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2025.913.0" />
<PackageReference Include="Sentry" Version="5.1.1" />
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
<PackageReference Include="SharpCompress" Version="0.39.0" />