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:
parent
5f68999893
commit
64b61108ad
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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>
|
||||
|
@ -67,6 +67,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
if (!LoadedBeatmapSuccessfully)
|
||||
return;
|
||||
|
||||
ScoreProcessor.ApplyNewJudgementsWhenFailed = true;
|
||||
|
||||
LoadComponentAsync(new GameplayChatDisplay(Room)
|
||||
{
|
||||
Expanded = { BindTarget = LeaderboardExpandedState },
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user