mirror of
https://github.com/ppy/osu.git
synced 2024-12-13 05:22:54 +08:00
Refactor for safety
This commit is contained in:
parent
2ae34530f7
commit
d74bf2a096
@ -17,51 +17,48 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
|
||||
private int maximumTinyDroplets;
|
||||
private int hitTinyDroplets;
|
||||
private int maximumBasicJudgements;
|
||||
private int currentBasicJudgements;
|
||||
|
||||
public CatchScoreProcessor()
|
||||
: base(new CatchRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
protected override double ComputeTotalScore()
|
||||
protected override double ComputeTotalScore(double comboRatio, double accuracyRatio, double bonusPortion)
|
||||
{
|
||||
double comboRatio = MaxComboPortion > 0 ? ComboPortion / MaxComboPortion : 1;
|
||||
double fruitHitsRatio = maximumTinyDroplets == 0 ? 0 : (double)hitTinyDroplets / maximumTinyDroplets;
|
||||
|
||||
const int tiny_droplets_portion = 400000;
|
||||
|
||||
return (
|
||||
((1000000 - tiny_droplets_portion) + tiny_droplets_portion * (1 - tinyDropletScale)) * comboRatio +
|
||||
tiny_droplets_portion * tinyDropletScale * fruitHitsRatio +
|
||||
BonusPortion
|
||||
) * ScoreMultiplier;
|
||||
return ((1000000 - tiny_droplets_portion) + tiny_droplets_portion * (1 - tinyDropletScale)) * comboRatio
|
||||
+ tiny_droplets_portion * tinyDropletScale * fruitHitsRatio
|
||||
+ bonusPortion;
|
||||
}
|
||||
|
||||
protected override void AddScoreChange(JudgementResult result)
|
||||
protected override double GetComboScoreChange(JudgementResult result)
|
||||
=> Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base));
|
||||
|
||||
protected override void ApplyScoreChange(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion += change.combo;
|
||||
BonusPortion += change.bonus;
|
||||
hitTinyDroplets += change.tinyDropletHits;
|
||||
base.ApplyScoreChange(result);
|
||||
|
||||
if (result.HitObject is TinyDroplet)
|
||||
hitTinyDroplets++;
|
||||
|
||||
if (result.Type.IsBasic())
|
||||
currentBasicJudgements++;
|
||||
}
|
||||
|
||||
protected override void RemoveScoreChange(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion -= change.combo;
|
||||
BonusPortion -= change.bonus;
|
||||
hitTinyDroplets -= change.tinyDropletHits;
|
||||
}
|
||||
base.RemoveScoreChange(result);
|
||||
|
||||
private (double combo, double bonus, int tinyDropletHits) computeScoreChange(JudgementResult result)
|
||||
{
|
||||
if (result.HitObject is TinyDroplet)
|
||||
return (0, 0, 1);
|
||||
hitTinyDroplets--;
|
||||
|
||||
if (result.Type.IsBonus())
|
||||
return (0, Judgement.ToNumericResult(result.Type), 0);
|
||||
|
||||
return (Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base)), 0, 0);
|
||||
if (result.Type.IsBasic())
|
||||
currentBasicJudgements--;
|
||||
}
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
@ -71,14 +68,16 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
if (storeResults)
|
||||
{
|
||||
maximumTinyDroplets = hitTinyDroplets;
|
||||
maximumBasicJudgements = currentBasicJudgements;
|
||||
|
||||
if (maximumTinyDroplets + MaxBasicJudgements == 0)
|
||||
if (maximumTinyDroplets + maximumBasicJudgements == 0)
|
||||
tinyDropletScale = 0;
|
||||
else
|
||||
tinyDropletScale = (double)maximumTinyDroplets / (maximumTinyDroplets + MaxBasicJudgements);
|
||||
tinyDropletScale = (double)maximumTinyDroplets / (maximumTinyDroplets + maximumBasicJudgements);
|
||||
}
|
||||
|
||||
hitTinyDroplets = 0;
|
||||
currentBasicJudgements = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,38 +16,14 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
{
|
||||
}
|
||||
|
||||
protected override double ComputeTotalScore()
|
||||
protected override double ComputeTotalScore(double comboRatio, double accuracyRatio, double bonusPortion)
|
||||
{
|
||||
double comboRatio = MaxComboPortion > 0 ? ComboPortion / MaxComboPortion : 1;
|
||||
double accuracyRatio = MaxBasicJudgements > 0 ? (double)CurrentBasicJudgements / MaxBasicJudgements : 1;
|
||||
|
||||
return (
|
||||
200000 * comboRatio +
|
||||
800000 * Math.Pow(Accuracy.Value, 2 + 2 * Accuracy.Value) * accuracyRatio +
|
||||
BonusPortion
|
||||
) * ScoreMultiplier;
|
||||
return 200000 * comboRatio
|
||||
+ 800000 * Math.Pow(Accuracy.Value, 2 + 2 * Accuracy.Value) * accuracyRatio
|
||||
+ bonusPortion;
|
||||
}
|
||||
|
||||
protected override void AddScoreChange(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion += change.combo;
|
||||
BonusPortion += change.bonus;
|
||||
}
|
||||
|
||||
protected override void RemoveScoreChange(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion -= change.combo;
|
||||
BonusPortion -= change.bonus;
|
||||
}
|
||||
|
||||
private (double combo, double bonus) computeScoreChange(JudgementResult result)
|
||||
{
|
||||
if (result.Type.IsBonus())
|
||||
return (0, Judgement.ToNumericResult(result.Type));
|
||||
|
||||
return (Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(400, combo_base)), 0);
|
||||
}
|
||||
protected override double GetComboScoreChange(JudgementResult result)
|
||||
=> Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(400, combo_base));
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,11 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
}
|
||||
|
||||
protected override double ComputeTotalScore()
|
||||
protected override double ComputeTotalScore(double comboRatio, double accuracyRatio, double bonusPortion)
|
||||
{
|
||||
double comboRatio = MaxComboPortion > 0 ? ComboPortion / MaxComboPortion : 1;
|
||||
double accuracyRatio = MaxBasicJudgements > 0 ? (double)CurrentBasicJudgements / MaxBasicJudgements : 1;
|
||||
|
||||
return (
|
||||
700000 * comboRatio +
|
||||
300000 * Math.Pow(Accuracy.Value, 10) * accuracyRatio +
|
||||
BonusPortion
|
||||
) * ScoreMultiplier;
|
||||
return 700000 * comboRatio
|
||||
+ 300000 * Math.Pow(Accuracy.Value, 10) * accuracyRatio
|
||||
+ bonusPortion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,46 +17,28 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
{
|
||||
}
|
||||
|
||||
protected override double ComputeTotalScore()
|
||||
protected override double ComputeTotalScore(double comboRatio, double accuracyRatio, double bonusPortion)
|
||||
{
|
||||
double comboRatio = MaxComboPortion > 0 ? ComboPortion / MaxComboPortion : 1;
|
||||
double accuracyRatio = MaxBasicJudgements > 0 ? (double)CurrentBasicJudgements / MaxBasicJudgements : 1;
|
||||
|
||||
return (
|
||||
250000 * comboRatio +
|
||||
750000 * Math.Pow(Accuracy.Value, 3.6) * accuracyRatio +
|
||||
BonusPortion
|
||||
) * ScoreMultiplier;
|
||||
return 250000 * comboRatio
|
||||
+ 750000 * Math.Pow(Accuracy.Value, 3.6) * accuracyRatio
|
||||
+ bonusPortion;
|
||||
}
|
||||
|
||||
protected override void AddScoreChange(JudgementResult result)
|
||||
protected override double GetBonusScoreChange(JudgementResult result) => base.GetBonusScoreChange(result) * strongScaleValue(result);
|
||||
|
||||
protected override double GetComboScoreChange(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion += change.combo;
|
||||
BonusPortion += change.bonus;
|
||||
return Judgement.ToNumericResult(result.Type)
|
||||
* Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(400, combo_base))
|
||||
* strongScaleValue(result);
|
||||
}
|
||||
|
||||
protected override void RemoveScoreChange(JudgementResult result)
|
||||
private double strongScaleValue(JudgementResult result)
|
||||
{
|
||||
var change = computeScoreChange(result);
|
||||
ComboPortion -= change.combo;
|
||||
BonusPortion -= change.bonus;
|
||||
}
|
||||
|
||||
private (double combo, double bonus) computeScoreChange(JudgementResult result)
|
||||
{
|
||||
double hitValue = Judgement.ToNumericResult(result.Type);
|
||||
|
||||
if (result.HitObject is StrongNestedHitObject strong)
|
||||
{
|
||||
double strongBonus = strong.Parent is DrumRollTick ? 3 : 7;
|
||||
hitValue *= strongBonus;
|
||||
}
|
||||
return strong.Parent is DrumRollTick ? 3 : 7;
|
||||
|
||||
if (result.Type.IsBonus())
|
||||
return (0, hitValue);
|
||||
|
||||
return (hitValue * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(400, combo_base)), 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Difficulty
|
||||
ScoreProcessor scoreProcessor = ruleset.CreateScoreProcessor();
|
||||
scoreProcessor.Mods.Value = perfectPlay.Mods;
|
||||
scoreProcessor.ApplyBeatmap(playableBeatmap);
|
||||
perfectPlay.TotalScore = scoreProcessor.MaxTotalScore;
|
||||
perfectPlay.TotalScore = scoreProcessor.MaximumTotalScore;
|
||||
|
||||
// compute rank achieved
|
||||
// default to SS, then adjust the rank with mods
|
||||
|
@ -90,10 +90,18 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// The maximum achievable total score.
|
||||
/// </summary>
|
||||
public long MaxTotalScore { get; private set; }
|
||||
public long MaximumTotalScore { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The sum of all accuracy-affecting judgements at the current time.
|
||||
/// The maximum sum of accuracy-affecting judgements at the current point in time.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used to compute accuracy.
|
||||
/// </remarks>
|
||||
private double currentMaximumBaseScore;
|
||||
|
||||
/// <summary>
|
||||
/// The sum of all accuracy-affecting judgements at the current point in time.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used to compute accuracy.
|
||||
@ -101,42 +109,34 @@ namespace osu.Game.Rulesets.Scoring
|
||||
private double currentBaseScore;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum sum of accuracy-affecting judgements at the current time.
|
||||
/// The count of all basic judgements in the beatmap.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used to compute accuracy.
|
||||
/// </remarks>
|
||||
private double currentMaxBaseScore;
|
||||
private int maximumCountBasicJudgements;
|
||||
|
||||
/// <summary>
|
||||
/// The total count of basic judgements in the beatmap.
|
||||
/// The count of basic judgements at the current point in time.
|
||||
/// </summary>
|
||||
protected int MaxBasicJudgements { get; private set; }
|
||||
private int currentCountBasicJudgements;
|
||||
|
||||
/// <summary>
|
||||
/// The current count of basic judgements by the player.
|
||||
/// The maximum combo score in the beatmap.
|
||||
/// </summary>
|
||||
protected int CurrentBasicJudgements { get; private set; }
|
||||
private double maximumComboPortion;
|
||||
|
||||
/// <summary>
|
||||
/// The current combo score.
|
||||
/// The combo score at the current point in time.
|
||||
/// </summary>
|
||||
protected double ComboPortion { get; set; }
|
||||
private double currentComboPortion;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum achievable combo score.
|
||||
/// The bonus score at the current point in time.
|
||||
/// </summary>
|
||||
protected double MaxComboPortion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current bonus score.
|
||||
/// </summary>
|
||||
protected double BonusPortion { get; set; }
|
||||
private double currentBonusPortion;
|
||||
|
||||
/// <summary>
|
||||
/// The total score multiplier.
|
||||
/// </summary>
|
||||
protected double ScoreMultiplier { get; private set; } = 1;
|
||||
private double scoreMultiplier = 1;
|
||||
|
||||
public Dictionary<HitResult, int> MaximumStatistics
|
||||
{
|
||||
@ -171,10 +171,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
Mods.ValueChanged += mods =>
|
||||
{
|
||||
ScoreMultiplier = 1;
|
||||
scoreMultiplier = 1;
|
||||
|
||||
foreach (var m in mods.NewValue)
|
||||
ScoreMultiplier *= m.ScoreMultiplier;
|
||||
scoreMultiplier *= m.ScoreMultiplier;
|
||||
|
||||
updateScore();
|
||||
};
|
||||
@ -207,15 +207,21 @@ namespace osu.Game.Rulesets.Scoring
|
||||
result.ComboAfterJudgement = Combo.Value;
|
||||
|
||||
if (result.Type.IsBasic())
|
||||
CurrentBasicJudgements++;
|
||||
currentCountBasicJudgements++;
|
||||
|
||||
if (result.Type.AffectsAccuracy())
|
||||
{
|
||||
currentMaxBaseScore += Judgement.ToNumericResult(result.Judgement.MaxResult);
|
||||
currentMaximumBaseScore += Judgement.ToNumericResult(result.Judgement.MaxResult);
|
||||
currentBaseScore += Judgement.ToNumericResult(result.Type);
|
||||
}
|
||||
|
||||
AddScoreChange(result);
|
||||
if (result.Type.IsBonus())
|
||||
currentBonusPortion += GetBonusScoreChange(result);
|
||||
|
||||
if (result.Type.AffectsCombo())
|
||||
currentComboPortion += GetComboScoreChange(result);
|
||||
|
||||
ApplyScoreChange(result);
|
||||
|
||||
hitEvents.Add(CreateHitEvent(result));
|
||||
lastHitObject = result.HitObject;
|
||||
@ -245,14 +251,20 @@ namespace osu.Game.Rulesets.Scoring
|
||||
return;
|
||||
|
||||
if (result.Type.IsBasic())
|
||||
CurrentBasicJudgements--;
|
||||
currentCountBasicJudgements--;
|
||||
|
||||
if (result.Type.AffectsAccuracy())
|
||||
{
|
||||
currentMaxBaseScore -= Judgement.ToNumericResult(result.Judgement.MaxResult);
|
||||
currentMaximumBaseScore -= Judgement.ToNumericResult(result.Judgement.MaxResult);
|
||||
currentBaseScore -= Judgement.ToNumericResult(result.Type);
|
||||
}
|
||||
|
||||
if (result.Type.IsBonus())
|
||||
currentBonusPortion -= GetBonusScoreChange(result);
|
||||
|
||||
if (result.Type.AffectsCombo())
|
||||
currentComboPortion -= GetComboScoreChange(result);
|
||||
|
||||
RemoveScoreChange(result);
|
||||
|
||||
Debug.Assert(hitEvents.Count > 0);
|
||||
@ -262,42 +274,37 @@ namespace osu.Game.Rulesets.Scoring
|
||||
updateScore();
|
||||
}
|
||||
|
||||
protected virtual void AddScoreChange(JudgementResult result)
|
||||
{
|
||||
if (result.Type.IsBonus())
|
||||
BonusPortion += Judgement.ToNumericResult(result.Type);
|
||||
protected virtual double GetBonusScoreChange(JudgementResult result) => Judgement.ToNumericResult(result.Type);
|
||||
|
||||
if (result.Type.AffectsCombo())
|
||||
ComboPortion += Judgement.ToNumericResult(result.Type) * (1 + result.ComboAfterJudgement / 10d);
|
||||
protected virtual double GetComboScoreChange(JudgementResult result) => Judgement.ToNumericResult(result.Type) * (1 + result.ComboAfterJudgement / 10d);
|
||||
|
||||
protected virtual void ApplyScoreChange(JudgementResult result)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void RemoveScoreChange(JudgementResult result)
|
||||
{
|
||||
if (result.Type.IsBonus())
|
||||
BonusPortion -= Judgement.ToNumericResult(result.Type);
|
||||
|
||||
if (result.Type.AffectsCombo())
|
||||
ComboPortion -= Judgement.ToNumericResult(result.Type) * (1 + result.ComboAfterJudgement / 10d);
|
||||
}
|
||||
|
||||
private void updateScore()
|
||||
{
|
||||
Accuracy.Value = currentMaxBaseScore > 0 ? currentBaseScore / currentMaxBaseScore : 1;
|
||||
TotalScore.Value = (long)Math.Round(ComputeTotalScore());
|
||||
Accuracy.Value = currentMaximumBaseScore > 0 ? currentBaseScore / currentMaximumBaseScore : 1;
|
||||
|
||||
double comboRatio = maximumComboPortion > 0 ? currentComboPortion / maximumComboPortion : 1;
|
||||
double accuracyRatio = maximumCountBasicJudgements > 0 ? (double)currentCountBasicJudgements / maximumCountBasicJudgements : 1;
|
||||
|
||||
TotalScore.Value = (long)Math.Round(ComputeTotalScore(comboRatio, accuracyRatio, currentBonusPortion) * scoreMultiplier);
|
||||
}
|
||||
|
||||
protected virtual double ComputeTotalScore()
|
||||
protected virtual double ComputeTotalScore(double comboRatio, double accuracyRatio, double bonusPortion)
|
||||
{
|
||||
double comboRatio = MaxComboPortion > 0 ? ComboPortion / MaxComboPortion : 1;
|
||||
double accuracyRatio = MaxBasicJudgements > 0 ? (double)CurrentBasicJudgements / MaxBasicJudgements : 1;
|
||||
|
||||
return
|
||||
(int)Math.Round
|
||||
((
|
||||
700000 * comboRatio +
|
||||
300000 * Math.Pow(Accuracy.Value, 10) * accuracyRatio +
|
||||
BonusPortion
|
||||
) * ScoreMultiplier);
|
||||
bonusPortion
|
||||
) * scoreMultiplier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -313,22 +320,22 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
if (storeResults)
|
||||
{
|
||||
MaxComboPortion = ComboPortion;
|
||||
MaxBasicJudgements = CurrentBasicJudgements;
|
||||
maximumComboPortion = currentComboPortion;
|
||||
maximumCountBasicJudgements = currentCountBasicJudgements;
|
||||
|
||||
maximumResultCounts.Clear();
|
||||
maximumResultCounts.AddRange(scoreResultCounts);
|
||||
|
||||
MaxTotalScore = TotalScore.Value;
|
||||
MaximumTotalScore = TotalScore.Value;
|
||||
}
|
||||
|
||||
scoreResultCounts.Clear();
|
||||
|
||||
currentBaseScore = 0;
|
||||
currentMaxBaseScore = 0;
|
||||
CurrentBasicJudgements = 0;
|
||||
ComboPortion = 0;
|
||||
BonusPortion = 0;
|
||||
currentMaximumBaseScore = 0;
|
||||
currentCountBasicJudgements = 0;
|
||||
currentComboPortion = 0;
|
||||
currentBonusPortion = 0;
|
||||
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
@ -338,7 +345,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
HighestCombo.Value = 0;
|
||||
|
||||
currentBaseScore = 0;
|
||||
currentMaxBaseScore = 0;
|
||||
currentMaximumBaseScore = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user