1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 10:07:52 +08:00

Change S rank to require no miss

This commit is contained in:
Dean Herbert 2024-01-19 18:43:15 +09:00
parent 7f31070b87
commit c8521b49cd
No known key found for this signature in database
6 changed files with 51 additions and 12 deletions

View File

@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Catch.Scoring
return baseIncrease * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base)); return baseIncrease * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base));
} }
public override ScoreRank RankFromAccuracy(double accuracy) public override ScoreRank RankFromScore(double accuracy, Dictionary<HitResult, int> results)
{ {
if (accuracy == accuracy_cutoff_x) if (accuracy == accuracy_cutoff_x)
return ScoreRank.X; return ScoreRank.X;

View File

@ -1,9 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Osu.Scoring namespace osu.Game.Rulesets.Osu.Scoring
{ {
@ -14,6 +16,22 @@ namespace osu.Game.Rulesets.Osu.Scoring
{ {
} }
public override ScoreRank RankFromScore(double accuracy, Dictionary<HitResult, int> results)
{
ScoreRank rank = base.RankFromScore(accuracy, results);
switch (rank)
{
case ScoreRank.S:
case ScoreRank.X:
if (results.GetValueOrDefault(HitResult.Miss) > 0)
rank = ScoreRank.A;
break;
}
return rank;
}
protected override HitEvent CreateHitEvent(JudgementResult result) protected override HitEvent CreateHitEvent(JudgementResult result)
=> base.CreateHitEvent(result).With((result as OsuHitCircleJudgementResult)?.CursorPositionAtHit); => base.CreateHitEvent(result).With((result as OsuHitCircleJudgementResult)?.CursorPositionAtHit);
} }

View File

@ -2,9 +2,11 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Taiko.Scoring namespace osu.Game.Rulesets.Taiko.Scoring
{ {
@ -33,6 +35,22 @@ namespace osu.Game.Rulesets.Taiko.Scoring
* strongScaleValue(result); * strongScaleValue(result);
} }
public override ScoreRank RankFromScore(double accuracy, Dictionary<HitResult, int> results)
{
ScoreRank rank = base.RankFromScore(accuracy, results);
switch (rank)
{
case ScoreRank.S:
case ScoreRank.X:
if (results.GetValueOrDefault(HitResult.Miss) == 0)
rank = ScoreRank.A;
break;
}
return rank;
}
public override int GetBaseScoreForResult(HitResult result) public override int GetBaseScoreForResult(HitResult result)
{ {
switch (result) switch (result)

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -96,6 +97,14 @@ namespace osu.Game.Tests.Visual.Ranking
{ {
var scoreProcessor = ruleset.CreateScoreProcessor(); var scoreProcessor = ruleset.CreateScoreProcessor();
var statistics = new Dictionary<HitResult, int>
{
{ HitResult.Miss, 1 },
{ HitResult.Meh, 50 },
{ HitResult.Good, 100 },
{ HitResult.Great, 300 },
};
return new ScoreInfo return new ScoreInfo
{ {
User = new APIUser User = new APIUser
@ -109,15 +118,9 @@ namespace osu.Game.Tests.Visual.Ranking
TotalScore = 2845370, TotalScore = 2845370,
Accuracy = accuracy, Accuracy = accuracy,
MaxCombo = 999, MaxCombo = 999,
Rank = scoreProcessor.RankFromAccuracy(accuracy), Rank = scoreProcessor.RankFromScore(accuracy, statistics),
Date = DateTimeOffset.Now, Date = DateTimeOffset.Now,
Statistics = Statistics = statistics,
{
{ HitResult.Miss, 1 },
{ HitResult.Meh, 50 },
{ HitResult.Good, 100 },
{ HitResult.Great, 300 },
}
}; };
} }
} }

View File

@ -370,7 +370,7 @@ namespace osu.Game.Rulesets.Scoring
if (rank.Value == ScoreRank.F) if (rank.Value == ScoreRank.F)
return; return;
rank.Value = RankFromAccuracy(Accuracy.Value); rank.Value = RankFromScore(Accuracy.Value, ScoreResultCounts);
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>()) foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
rank.Value = mod.AdjustRank(Rank.Value, Accuracy.Value); rank.Value = mod.AdjustRank(Rank.Value, Accuracy.Value);
} }
@ -505,7 +505,7 @@ namespace osu.Game.Rulesets.Scoring
/// <summary> /// <summary>
/// Given an accuracy (0..1), return the correct <see cref="ScoreRank"/>. /// Given an accuracy (0..1), return the correct <see cref="ScoreRank"/>.
/// </summary> /// </summary>
public virtual ScoreRank RankFromAccuracy(double accuracy) public virtual ScoreRank RankFromScore(double accuracy, Dictionary<HitResult, int> results)
{ {
if (accuracy == accuracy_cutoff_x) if (accuracy == accuracy_cutoff_x)
return ScoreRank.X; return ScoreRank.X;

View File

@ -280,7 +280,7 @@ namespace osu.Game.Scoring.Legacy
{ {
scoreInfo.Accuracy = StandardisedScoreMigrationTools.ComputeAccuracy(scoreInfo); scoreInfo.Accuracy = StandardisedScoreMigrationTools.ComputeAccuracy(scoreInfo);
var rank = currentRuleset.CreateScoreProcessor().RankFromAccuracy(scoreInfo.Accuracy); var rank = currentRuleset.CreateScoreProcessor().RankFromScore(scoreInfo.Accuracy, scoreInfo.Statistics);
foreach (var mod in scoreInfo.Mods.OfType<IApplicableToScoreProcessor>()) foreach (var mod in scoreInfo.Mods.OfType<IApplicableToScoreProcessor>())
rank = mod.AdjustRank(rank, scoreInfo.Accuracy); rank = mod.AdjustRank(rank, scoreInfo.Accuracy);