1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-26 18:52:55 +08:00

Merge pull request #26751 from frenzibyte/fix-multiplayer-fail-freezing-score

Fix score processor no longer applying results when failing in multiplayer match
This commit is contained in:
Dean Herbert 2024-01-29 19:51:31 +09:00 committed by GitHub
commit a1fe5eedd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 11 deletions

View File

@ -3,13 +3,18 @@
#nullable disable #nullable disable
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.OnlinePlay.Multiplayer; using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
@ -19,14 +24,37 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
private MultiplayerPlayer player; private MultiplayerPlayer player;
[SetUpSteps] [Test]
public override void SetUpSteps() public void TestGameplay()
{ {
base.SetUpSteps(); setup();
AddUntilStep("wait for gameplay start", () => player.LocalUserPlaying.Value);
}
[Test]
public void TestFail()
{
setup(() => new[] { new OsuModAutopilot() });
AddUntilStep("wait for gameplay start", () => player.LocalUserPlaying.Value);
AddStep("set health zero", () => player.ChildrenOfType<HealthProcessor>().Single().Health.Value = 0);
AddUntilStep("wait for fail", () => player.ChildrenOfType<HealthProcessor>().Single().HasFailed);
AddAssert("fail animation not shown", () => !player.GameplayState.HasFailed);
// ensure that even after reaching a failed state, score processor keeps accounting for new hit results.
// the testing method used here (autopilot + hold key) is sort-of dodgy, but works enough.
AddAssert("score is zero", () => player.GameplayState.ScoreProcessor.TotalScore.Value == 0);
AddStep("hold key", () => player.ChildrenOfType<OsuInputManager.RulesetKeyBindingContainer>().First().TriggerPressed(OsuAction.LeftButton));
AddUntilStep("score changed", () => player.GameplayState.ScoreProcessor.TotalScore.Value > 0);
}
private void setup(Func<IReadOnlyList<Mod>> mods = null)
{
AddStep("set beatmap", () => AddStep("set beatmap", () =>
{ {
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
SelectedMods.Value = mods?.Invoke() ?? Array.Empty<Mod>();
}); });
AddStep("Start track playing", () => AddStep("Start track playing", () =>
@ -52,11 +80,5 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("gameplay clock is not paused", () => !player.ChildrenOfType<GameplayClockContainer>().Single().IsPaused.Value); AddUntilStep("gameplay clock is not paused", () => !player.ChildrenOfType<GameplayClockContainer>().Single().IsPaused.Value);
AddAssert("gameplay clock is running", () => player.ChildrenOfType<GameplayClockContainer>().Single().IsRunning); AddAssert("gameplay clock is running", () => player.ChildrenOfType<GameplayClockContainer>().Single().IsRunning);
} }
[Test]
public void TestGameplay()
{
AddUntilStep("wait for gameplay start", () => player.LocalUserPlaying.Value);
}
} }
} }

View File

@ -181,6 +181,8 @@ namespace osu.Game.Rulesets.Scoring
private readonly List<HitEvent> hitEvents = new List<HitEvent>(); private readonly List<HitEvent> hitEvents = new List<HitEvent>();
private HitObject? lastHitObject; private HitObject? lastHitObject;
public bool ApplyNewJudgementsWhenFailed { get; set; }
public ScoreProcessor(Ruleset ruleset) public ScoreProcessor(Ruleset ruleset)
{ {
Ruleset = ruleset; Ruleset = ruleset;
@ -211,7 +213,7 @@ namespace osu.Game.Rulesets.Scoring
result.ComboAtJudgement = Combo.Value; result.ComboAtJudgement = Combo.Value;
result.HighestComboAtJudgement = HighestCombo.Value; result.HighestComboAtJudgement = HighestCombo.Value;
if (result.FailedAtJudgement) if (result.FailedAtJudgement && !ApplyNewJudgementsWhenFailed)
return; return;
ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) + 1; ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) + 1;
@ -267,7 +269,7 @@ namespace osu.Game.Rulesets.Scoring
Combo.Value = result.ComboAtJudgement; Combo.Value = result.ComboAtJudgement;
HighestCombo.Value = result.HighestComboAtJudgement; HighestCombo.Value = result.HighestComboAtJudgement;
if (result.FailedAtJudgement) if (result.FailedAtJudgement && !ApplyNewJudgementsWhenFailed)
return; return;
ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) - 1; ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) - 1;

View File

@ -67,6 +67,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
if (!LoadedBeatmapSuccessfully) if (!LoadedBeatmapSuccessfully)
return; return;
ScoreProcessor.ApplyNewJudgementsWhenFailed = true;
LoadComponentAsync(new GameplayChatDisplay(Room) LoadComponentAsync(new GameplayChatDisplay(Room)
{ {
Expanded = { BindTarget = LeaderboardExpandedState }, Expanded = { BindTarget = LeaderboardExpandedState },