diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index c241c4cf41..3550d561c1 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Database; using osu.Game.Rulesets.Objects.Types; @@ -60,6 +61,11 @@ namespace osu.Game.Rulesets.Mania.Objects tickSpacing = timingPoint.BeatLength / difficulty.SliderTickRate; } + /// + /// Total number of hold note ticks. + /// + public int TotalTicks => Ticks.Count(); + /// /// The scoring scoring ticks of the hold note. /// diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 7a9572a0c7..2f4ce075c3 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -1,8 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -10,6 +13,52 @@ namespace osu.Game.Rulesets.Mania.Scoring { internal class ManiaScoreProcessor : ScoreProcessor { + /// + /// The maximum score achievable. + /// Does _not_ include bonus score - for bonus score see . + /// + private const int max_score = 1000000; + + /// + /// The amount of the score attributed to combo. + /// + private const double combo_portion_max = max_score * 0.2; + + /// + /// The amount of the score attributed to accuracy. + /// + private const double accuracy_portion_max = max_score * 0.8; + + /// + /// The cumulative combo portion of the score. + /// + private double comboScore => combo_portion_max * comboPortion / maxComboPortion; + + /// + /// The cumulative accuracy portion of the score. + /// + private double accuracyScore => accuracy_portion_max * Math.Pow(Accuracy, 4) * totalHits / maxTotalHits; + + /// + /// The cumulative bonus score. + /// This is added on top of , thus the total score can exceed . + /// + private double bonusScore; + + private double maxComboPortion; + private double comboPortion; + private int maxTotalHits; + private int totalHits; + + private double hpIncreaseBad; + private double hpIncreaseOk; + private double hpIncreaseGood; + private double hpIncreaseGreat; + private double hpIncreasePerfect; + private double hpIncreaseTick; + private double hpIncreaseTickMiss; + private double hpIncreaseMiss; + public ManiaScoreProcessor() { } @@ -19,8 +68,107 @@ namespace osu.Game.Rulesets.Mania.Scoring { } + protected override void ComputeTargets(Beatmap beatmap) + { + foreach (var obj in beatmap.HitObjects) + { + if (obj is Note) + { + AddJudgement(new ManiaJudgement + { + Result = HitResult.Hit, + ManiaResult = ManiaHitResult.Perfect + }); + } + else if (obj is HoldNote) + { + // Head + AddJudgement(new ManiaJudgement + { + Result = HitResult.Hit, + ManiaResult = ManiaJudgement.MAX_HIT_RESULT + }); + + // Ticks + for (int i = 0; i < ((HoldNote)obj).TotalTicks; i++) + { + AddJudgement(new HoldNoteTickJudgement + { + Result = HitResult.Hit, + ManiaResult = ManiaJudgement.MAX_HIT_RESULT, + }); + } + + AddJudgement(new HoldNoteTailJudgement + { + Result = HitResult.Hit, + ManiaResult = ManiaJudgement.MAX_HIT_RESULT + }); + } + } + + maxTotalHits = totalHits; + maxComboPortion = comboPortion; + } + protected override void OnNewJudgement(ManiaJudgement judgement) { + bool isTick = judgement is HoldNoteTickJudgement; + + if (!isTick) + totalHits++; + + switch (judgement.Result) + { + case HitResult.Miss: + if (isTick) + Health.Value += hpIncreaseTickMiss; + else + Health.Value += hpIncreaseMiss; + break; + case HitResult.Hit: + if (isTick) + { + Health.Value += hpIncreaseTick; + bonusScore += judgement.ResultValueForScore; + } + else + { + switch (judgement.ManiaResult) + { + case ManiaHitResult.Bad: + Health.Value += hpIncreaseBad; + break; + case ManiaHitResult.Ok: + Health.Value += hpIncreaseOk; + break; + case ManiaHitResult.Good: + Health.Value += hpIncreaseGood; + break; + case ManiaHitResult.Great: + Health.Value += hpIncreaseGreat; + break; + case ManiaHitResult.Perfect: + Health.Value += hpIncreasePerfect; + break; + } + + comboPortion += judgement.ResultValueForScore; + } + break; + } + + int scoreForAccuracy = 0; + int maxScoreForAccuracy = 0; + + foreach (var j in Judgements) + { + scoreForAccuracy += j.ResultValueForAccuracy; + maxScoreForAccuracy += j.MaxResultValueForAccuracy; + } + + Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; + TotalScore.Value = comboScore + accuracyScore + bonusScore; } protected override void Reset()