diff --git a/Quaver.API/Replays/Virtual/VirtualReplayPlayer.cs b/Quaver.API/Replays/Virtual/VirtualReplayPlayer.cs index 32b79b595..701feecb3 100644 --- a/Quaver.API/Replays/Virtual/VirtualReplayPlayer.cs +++ b/Quaver.API/Replays/Virtual/VirtualReplayPlayer.cs @@ -142,39 +142,7 @@ public void PlayNextFrame() { if (CurrentFrame >= Replay.Frames.Count && !ExtendedFailingReplay && !DontExtendReplay) { - // Handle when the replay isn't extended enough to have enough misses to cause a failure. - var totalJudgementCount = ScoreProcessor.GetTotalJudgementCount(); - var totalScoredJudgements = ScoreProcessor.TotalJudgementCount; - var judgementDifference = totalJudgementCount - totalScoredJudgements; - - if (judgementDifference != 0) - { - for (var i = totalScoredJudgements; i < totalJudgementCount; i++) - { - var obj = Map.GetHitObjectAtJudgementIndex(i); - - var hitStat = obj.Type switch - { - HitObjectType.Normal => new HitStat(HitStatType.Miss, KeyPressType.None, obj, obj.StartTime, - Judgement.Miss, int.MinValue, ScoreProcessor.Accuracy, ScoreProcessor.Health), - HitObjectType.Mine => new HitStat(HitStatType.Hit, KeyPressType.None, obj, obj.StartTime, - Judgement.Marv, 0, ScoreProcessor.Accuracy, ScoreProcessor.Health), - _ => throw new ArgumentOutOfRangeException(nameof(obj.Type), obj.Type, - "Unhandled note type") - }; - - ScoreProcessor.CalculateScore(hitStat); - - ScoreProcessor.Stats.Add(hitStat); - - if (!ScoreProcessor.Failed) - continue; - - ExtendedFailingReplay = true; - return; - } - } - + ExtendWithRemainingHitObjects(); ExtendedFailingReplay = true; return; } @@ -197,6 +165,54 @@ public void PlayNextFrame() } } + /// + /// Extends incomplete replays with misses from objects that are still active. + /// + private void ExtendWithRemainingHitObjects() + { + ActiveHitObjectsToRemove = new List(); + ActiveHeldLongNotesToRemove = new List(); + ActiveMinesToRemove = new List(); + + foreach (var hitObject in ActiveHeldLongNotes.OrderBy(x => x.EndTime).ToList()) + { + var missedReleaseJudgement = ScoreProcessor.Windows.LNMissJudgement.Value; + var stat = new HitStat(HitStatType.Miss, KeyPressType.None, hitObject, hitObject.EndTime, + missedReleaseJudgement, int.MinValue, ScoreProcessor.Accuracy, ScoreProcessor.Health); + + ScoreProcessor.CalculateScore(missedReleaseJudgement, true); + ScoreProcessor.Stats.Add(stat); + ActiveHeldLongNotesToRemove.Add(hitObject); + + if (ScoreProcessor.Failed) + return; + } + + foreach (var hitObject in ActiveHitObjects.OrderBy(x => x.StartTime).ToList()) + { + AddMissedHitObject(hitObject); + ActiveHitObjectsToRemove.Add(hitObject); + + if (ScoreProcessor.Failed) + return; + } + } + + private void AddMissedHitObject(HitObjectInfo hitObject) + { + var stat = new HitStat(HitStatType.Miss, KeyPressType.None, hitObject, hitObject.StartTime, + Judgement.Miss, int.MinValue, ScoreProcessor.Accuracy, ScoreProcessor.Health); + + ScoreProcessor.CalculateScore(stat); + ScoreProcessor.Stats.Add(stat); + + if (!hitObject.IsLongNote) + return; + + ScoreProcessor.CalculateScore(Judgement.Miss, true, false); + ScoreProcessor.Stats.Add(stat); + } + /// /// Plays the entire replay. ///