1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 02:32:59 +08:00

Move solution to multiplayer flow instead

This commit is contained in:
Salman Ahmed 2024-01-28 00:34:23 +03:00
parent 5f68999893
commit 64b61108ad
17 changed files with 41 additions and 59 deletions

View File

@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
Player.ScoreProcessor.NewJudgement += _ => judged = true;
});
AddUntilStep("swell judged", () => judged);
AddAssert("not failed", () => !Player.GameplayState.ShownFailAnimation);
AddAssert("not failed", () => !Player.GameplayState.HasFailed);
}
}
}

View File

@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override void AddCheckSteps()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("wait for fail overlay", () => ((FailPlayer)Player).FailOverlay.State.Value == Visibility.Visible);
// The pause screen and fail animation both ramp frequency.

View File

@ -22,9 +22,9 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override void AddCheckSteps()
{
AddUntilStep("player is playing", () => Player.LocalUserPlaying.Value);
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddAssert("player is not playing", () => !Player.LocalUserPlaying.Value);
AddUntilStep("wait for multiple judgements", () => ((FailPlayer)Player).DrawableRuleset.Playfield.AllEntries.Count(e => e.Judged) > 1);
AddUntilStep("wait for multiple judgements", () => ((FailPlayer)Player).ScoreProcessor.JudgedHits > 1);
AddAssert("total number of results == 1", () =>
{
var score = new ScoreInfo { Ruleset = Ruleset.Value };

View File

@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestPauseAfterFail()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("fail overlay shown", () => Player.FailOverlayVisible);
confirmClockRunning(false);
@ -240,7 +240,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestExitFromFailedGameplayAfterFailAnimation()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("wait for fail overlay shown", () => Player.FailOverlayVisible);
confirmClockRunning(false);
@ -252,7 +252,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestExitFromFailedGameplayDuringFailAnimation()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
// will finish the fail animation and show the fail/pause screen.
pauseViaBackAction();
@ -266,7 +266,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestQuickRetryFromFailedGameplay()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddStep("quick retry", () => Player.GameplayClockContainer.ChildrenOfType<HotkeyRetryOverlay>().First().Action?.Invoke());
confirmExited();
@ -275,7 +275,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestQuickExitFromFailedGameplay()
{
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
exitViaQuickExitAction();
confirmExited();
@ -380,7 +380,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
confirmClockRunning(false);
confirmNotExited();
AddAssert("player not failed", () => !Player.GameplayState.ShownFailAnimation);
AddAssert("player not failed", () => !Player.GameplayState.HasFailed);
AddAssert("pause overlay shown", () => Player.PauseOverlayVisible);
}

View File

@ -171,7 +171,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("wait for token request", () => Player.TokenCreationRequested);
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddStep("exit", () => Player.Exit());
AddAssert("ensure no submission", () => Player.SubmittedScore == null);
@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.Gameplay
addFakeHit();
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("wait for submission", () => Player.SubmittedScore != null);
AddAssert("ensure failing submission", () => Player.SubmittedScore.ScoreInfo.Passed == false);

View File

@ -353,7 +353,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("send failed", () => spectatorClient.SendEndPlay(streamingUser.Id, SpectatedUserState.Failed));
AddUntilStep("state is failed", () => spectatorClient.WatchedUserStates[streamingUser.Id].State == SpectatedUserState.Failed);
AddUntilStep("wait for player to fail", () => player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for player to fail", () => player.GameplayState.HasFailed);
start();
sendFrames();

View File

@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("set storyboard duration to 0.6s", () => currentStoryboardDuration = 600);
});
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.CurrentTime >= currentStoryboardDuration);
AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible);
}
@ -116,7 +116,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("set storyboard duration to 0s", () => currentStoryboardDuration = 0);
});
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.CurrentTime >= currentStoryboardDuration);
AddUntilStep("wait for fail", () => Player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible);
AddUntilStep("wait for button clickable", () => Player.ChildrenOfType<SaveFailedScoreButton>().First().ChildrenOfType<OsuClickableContainer>().First().Enabled.Value);

View File

@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Mods
Position = new Vector2(i * 50)
}).Cast<HitObject>().ToList()
},
PassCondition = () => Player.GameplayState.ShownFailAnimation && Player.ScoreProcessor.JudgedHits >= 3
PassCondition = () => Player.GameplayState.HasFailed && Player.ScoreProcessor.JudgedHits >= 3
});
[Test]
@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.Mods
Position = new Vector2(i * 50)
}).Cast<HitObject>().ToList()
},
PassCondition = () => Player.GameplayState.ShownFailAnimation && Player.ScoreProcessor.JudgedHits >= 1
PassCondition = () => Player.GameplayState.HasFailed && Player.ScoreProcessor.JudgedHits >= 1
});
}
}

View File

@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
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.ShownFailAnimation);
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.

View File

@ -392,7 +392,7 @@ namespace osu.Game.Tests.Visual.Navigation
return (player = Game.ScreenStack.CurrentScreen as Player) != null;
});
AddUntilStep("wait for fail", () => player.GameplayState.ShownFailAnimation);
AddUntilStep("wait for fail", () => player.GameplayState.HasFailed);
AddUntilStep("wait for track stop", () => !Game.MusicController.IsPlaying);
AddAssert("Ensure time before preview point", () => Game.MusicController.CurrentTrack.CurrentTime < beatmap().BeatmapInfo.Metadata.PreviewTime);

View File

@ -251,7 +251,7 @@ namespace osu.Game.Online.Spectator
if (state.HasPassed)
currentState.State = SpectatedUserState.Passed;
else if (state.ShownFailAnimation)
else if (state.HasFailed)
currentState.State = SpectatedUserState.Failed;
else
currentState.State = SpectatedUserState.Quit;

View File

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

View File

@ -78,25 +78,6 @@ namespace osu.Game.Rulesets.UI
}
}
/// <summary>
/// All the <see cref="HitObjectLifetimeEntry"/>s contained in this <see cref="Playfield"/> and all <see cref="NestedPlayfields"/>.
/// </summary>
public IEnumerable<HitObjectLifetimeEntry> AllEntries
{
get
{
if (HitObjectContainer == null)
return Enumerable.Empty<HitObjectLifetimeEntry>();
var enumerable = HitObjectContainer.Entries;
if (nestedPlayfields.Count != 0)
enumerable = enumerable.Concat(NestedPlayfields.SelectMany(p => p.AllEntries));
return enumerable;
}
}
/// <summary>
/// All <see cref="Playfield"/>s nested inside this <see cref="Playfield"/>.
/// </summary>

View File

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

View File

@ -46,12 +46,9 @@ namespace osu.Game.Screens.Play
public bool HasPassed { get; set; }
/// <summary>
/// Whether the user failed during gameplay and the fail animation has been displayed.
/// Whether the user failed during gameplay. This is only set when the gameplay session has completed due to the fail.
/// </summary>
/// <remarks>
/// In multiplayer, this is never set to <c>true</c> even if the player reached zero health, due to <see cref="PlayerConfiguration.AllowFailAnimation"/> being turned off.
/// </remarks>
public bool ShownFailAnimation { get; set; }
public bool HasFailed { get; set; }
/// <summary>
/// Whether the user quit gameplay without having either passed or failed.

View File

@ -357,9 +357,6 @@ namespace osu.Game.Screens.Play
DrawableRuleset.NewResult += r =>
{
if (GameplayState.ShownFailAnimation)
return;
HealthProcessor.ApplyResult(r);
ScoreProcessor.ApplyResult(r);
GameplayState.ApplyResult(r);
@ -367,9 +364,6 @@ namespace osu.Game.Screens.Play
DrawableRuleset.RevertResult += r =>
{
if (GameplayState.ShownFailAnimation)
return;
HealthProcessor.RevertResult(r);
ScoreProcessor.RevertResult(r);
};
@ -495,7 +489,7 @@ namespace osu.Game.Screens.Play
private void updateGameplayState()
{
bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value && !GameplayState.ShownFailAnimation;
bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value && !GameplayState.HasFailed;
OverlayActivationMode.Value = inGameplay ? OverlayActivation.Disabled : OverlayActivation.UserTriggered;
localUserPlaying.Value = inGameplay;
}
@ -592,7 +586,7 @@ namespace osu.Game.Screens.Play
if (showDialogFirst && !pauseOrFailDialogVisible)
{
// if the fail animation is currently in progress, accelerate it (it will show the pause dialog on completion).
if (ValidForResume && GameplayState.ShownFailAnimation)
if (ValidForResume && GameplayState.HasFailed)
{
failAnimationContainer.FinishTransforms(true);
return false;
@ -739,7 +733,7 @@ namespace osu.Game.Screens.Play
}
// Only show the completion screen if the player hasn't failed
if (GameplayState.ShownFailAnimation)
if (GameplayState.HasFailed)
return;
GameplayState.HasPassed = true;
@ -928,11 +922,11 @@ namespace osu.Game.Screens.Play
if (Configuration.AllowFailAnimation)
{
Debug.Assert(!GameplayState.ShownFailAnimation);
Debug.Assert(!GameplayState.HasFailed);
Debug.Assert(!GameplayState.HasPassed);
Debug.Assert(!GameplayState.HasQuit);
GameplayState.ShownFailAnimation = true;
GameplayState.HasFailed = true;
updateGameplayState();
@ -1008,13 +1002,13 @@ namespace osu.Game.Screens.Play
// replays cannot be paused and exit immediately
&& !DrawableRuleset.HasReplayLoaded.Value
// cannot pause if we are already in a fail state
&& !GameplayState.ShownFailAnimation;
&& !GameplayState.HasFailed;
private bool canResume =>
// cannot resume from a non-paused state
GameplayClockContainer.IsPaused.Value
// cannot resume if we are already in a fail state
&& !GameplayState.ShownFailAnimation
&& !GameplayState.HasFailed
// already resuming
&& !IsResuming;
@ -1148,7 +1142,7 @@ namespace osu.Game.Screens.Play
{
Debug.Assert(resultsDisplayDelegate == null);
if (!GameplayState.ShownFailAnimation)
if (!GameplayState.HasFailed)
GameplayState.HasQuit = true;
if (DrawableRuleset.ReplayScore == null)

View File

@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play
if (!touchActive.Value)
return;
if (gameplayState.HasPassed || gameplayState.ShownFailAnimation || gameplayState.HasQuit)
if (gameplayState.HasPassed || gameplayState.HasFailed || gameplayState.HasQuit)
return;
if (gameplayState.Score.ScoreInfo.Mods.OfType<ModTouchDevice>().Any())