diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index 0de2b6a980..d8817e563c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -19,6 +19,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD.JudgementCounter; using osu.Game.Tests.Beatmaps.IO; using osu.Game.Tests.Gameplay; using osu.Game.Tests.Visual.Multiplayer; @@ -167,14 +168,16 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestSpectatingDuringGameplay() { start(); - sendFrames(300); + sendFrames(300, initialResultCount: 100); loadSpectatingScreen(); waitForPlayerCurrent(); - sendFrames(300); + sendFrames(300, initialResultCount: 100); AddUntilStep("playing from correct point in time", () => player.ChildrenOfType().First().FrameStableClock.CurrentTime, () => Is.GreaterThan(30000)); + AddAssert("check judgement counts are correct", () => player.ChildrenOfType().Single().Counters.Sum(c => c.ResultCount.Value), + () => Is.GreaterThanOrEqualTo(100)); } [Test] @@ -405,9 +408,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void checkPaused(bool state) => AddUntilStep($"game is {(state ? "paused" : "playing")}", () => player.ChildrenOfType().First().IsPaused.Value == state); - private void sendFrames(int count = 10, double startTime = 0) + private void sendFrames(int count = 10, double startTime = 0, int initialResultCount = 0) { - AddStep("send frames", () => spectatorClient.SendFramesFromUser(streamingUser.Id, count, startTime)); + AddStep("send frames", () => spectatorClient.SendFramesFromUser(streamingUser.Id, count, startTime, initialResultCount)); } private void loadSpectatingScreen() diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 44ddb8c187..9752918dfb 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -181,6 +181,8 @@ namespace osu.Game.Rulesets.Scoring } } + public IReadOnlyDictionary Statistics => ScoreResultCounts; + private bool beatmapApplied; protected readonly Dictionary ScoreResultCounts = new Dictionary(); diff --git a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs index 5aef85fa13..c27e7f15ca 100644 --- a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs +++ b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs @@ -13,6 +13,8 @@ using osu.Game.Online.API; using osu.Game.Online.Spectator; using osu.Game.Replays.Legacy; using osu.Game.Rulesets; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; @@ -99,13 +101,24 @@ namespace osu.Game.Tests.Visual.Spectator /// The user to send frames for. /// The total number of frames to send. /// The time to start gameplay frames from. - public void SendFramesFromUser(int userId, int count, double startTime = 0) + /// Add a number of misses to frame header data for testing purposes. + public void SendFramesFromUser(int userId, int count, double startTime = 0, int initialResultCount = 0) { var frames = new List(); int currentFrameIndex = userNextFrameDictionary[userId]; int lastFrameIndex = currentFrameIndex + count - 1; + var scoreProcessor = new ScoreProcessor(rulesetStore.GetRuleset(0)!.CreateInstance()); + + for (int i = 0; i < initialResultCount; i++) + { + scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement()) + { + Type = HitResult.Miss, + }); + } + for (; currentFrameIndex <= lastFrameIndex; currentFrameIndex++) { // This is done in the next frame so that currentFrameIndex is updated to the correct value. @@ -130,7 +143,16 @@ namespace osu.Game.Tests.Visual.Spectator Combo = currentFrameIndex, TotalScore = (long)(currentFrameIndex * 123478 * RNG.NextDouble(0.99, 1.01)), Accuracy = RNG.NextDouble(0.98, 1), - }, new ScoreProcessor(rulesetStore.GetRuleset(0)!.CreateInstance()), frames.ToArray()); + Statistics = scoreProcessor.Statistics.ToDictionary(), + }, scoreProcessor, frames.ToArray()); + + if (initialResultCount > 0) + { + foreach (var f in frames) + f.Header = bundle.Header; + } + + scoreProcessor.ResetFromReplayFrame(frames.Last()); ((ISpectatorClient)this).UserSentFrames(userId, bundle); frames.Clear();