/// <summary> /// Returns the score processor to use. Loads hit stats from a replay if needed. /// </summary> /// <param name="screen"></param> /// <returns></returns> /// <exception cref="ArgumentOutOfRangeException"></exception> private static ScoreProcessor GetScoreProcessor(ResultScreen screen) { // If we already have stats (for example, this is a result screen right after a player finished playing a map), use them. if (screen.ScoreProcessor.Stats != null) { return(screen.ScoreProcessor); } // Otherwise, get the stats from a replay. Replay replay = null; // FIXME: unify this logic with watching a replay from a ResultScreen. try { switch (screen.ResultsType) { case ResultScreenType.Gameplay: case ResultScreenType.Replay: replay = screen.Replay; break; case ResultScreenType.Score: // Don't do anything for online replays since they aren't downloaded yet. if (!screen.Score.IsOnline) { replay = new Replay($"{ConfigManager.DataDirectory.Value}/r/{screen.Score.Id}.qr"); } break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { NotificationManager.Show(NotificationLevel.Error, "Unable to read replay file"); Logger.Error(e, LogType.Runtime); } // Load a replay if we got one. if (replay == null) { return(screen.ScoreProcessor); } var qua = ResultScreen.Map.LoadQua(); qua.ApplyMods(replay.Mods); var player = new VirtualReplayPlayer(replay, qua); player.PlayAllFrames(); return(player.ScoreProcessor); }
/// <summary> /// Ctor - /// </summary> /// <param name="screen"></param> internal ReplayInputManagerKeys(GameplayScreen screen) { Screen = screen; Replay = Screen.LoadedReplay; VirtualPlayer = new VirtualReplayPlayer(Replay, Screen.Map); VirtualPlayer.PlayAllFrames(); // Populate unique key presses/releases. for (var i = 0; i < screen.Map.GetKeyCount(); i++) { UniquePresses.Add(false); UniqueReleases.Add(false); } }
/// <summary> /// Ctor - /// </summary> /// <param name="screen"></param> internal ReplayInputManagerKeys(GameplayScreen screen) { Screen = screen; Replay = Screen.LoadedReplay; var windows = Screen.SpectatorClient != null ? JudgementWindowsDatabaseCache.Standard : JudgementWindowsDatabaseCache.Selected.Value; VirtualPlayer = new VirtualReplayPlayer(Replay, Screen.Map, windows, Screen.SpectatorClient != null); VirtualPlayer.PlayAllFrames(); // Populate unique key presses/releases. for (var i = 0; i < screen.Map.GetKeyCount(); i++) { UniquePresses.Add(false); UniqueReleases.Add(false); } }
/// <summary> /// Returns the score processor to use. Loads hit stats from a replay if needed. /// </summary> /// <returns></returns> /// <exception cref="ArgumentOutOfRangeException"></exception> public ScoreProcessor GetScoreProcessor() { // Handles the case when watching a replay in its entirety. This uses the preprocessed // ScoreProcessor/Replay from gameplay to get a 100% accurate score output. // Also avoids having to process the replay again (as done below). if (Gameplay != null && Gameplay.InReplayMode) { var im = Gameplay.Ruleset.InputManager as KeysInputManager; return(im?.ReplayInputManager.VirtualPlayer.ScoreProcessor); } // If we already have stats (for example, this is a result screen right after a player finished playing a map), use them. if (ScoreProcessor.Stats != null) { return(ScoreProcessor); } // Otherwise, get the stats from a replay. Replay replay = null; // FIXME: unify this logic with watching a replay from a ResultScreen. try { switch (ResultsType) { case ResultScreenType.Gameplay: case ResultScreenType.Replay: replay = Replay; break; case ResultScreenType.Score: // Don't do anything for online replays since they aren't downloaded yet. if (!Score.IsOnline) { replay = new Replay($"{ConfigManager.DataDirectory.Value}/r/{Score.Id}.qr"); } break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { NotificationManager.Show(NotificationLevel.Error, "Unable to read replay file"); Logger.Error(e, LogType.Runtime); } // Load a replay if we got one. if (replay == null) { return(ScoreProcessor); } var qua = Map.LoadQua(); qua.ApplyMods(replay.Mods); if (replay.Mods.HasFlag(ModIdentifier.Randomize)) { qua.RandomizeLanes(replay.RandomizeModifierSeed); } JudgementWindows windows = null; // ReSharper disable once CompareOfFloatsByEqualityOperator if (Score != null && Score.JudgementWindowPreset != JudgementWindowsDatabaseCache.Standard.Name && Score.JudgementWindowMarv != 0) { windows = new JudgementWindows() { Marvelous = Score.JudgementWindowMarv, Perfect = Score.JudgementWindowPerf, Great = Score.JudgementWindowGreat, Good = Score.JudgementWindowGood, Okay = Score.JudgementWindowOkay, Miss = Score.JudgementWindowMiss }; } var player = new VirtualReplayPlayer(replay, qua, windows); player.PlayAllFrames(); return(player.ScoreProcessor); }