From 290f8db341c7dc168bf7a93a80a364199bc19dcc Mon Sep 17 00:00:00 2001 From: Givikap120 Date: Sat, 26 Aug 2023 02:13:14 +0300 Subject: [PATCH] fixed stated problems removed functions from `Ruleset.cs` and added a `GetEffectiveDifficulty()` instead --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 40 ++++++++++++++-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 38 +++++++++++++-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 46 ++++++++++++++++--- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 37 +++++++++++++-- osu.Game/Rulesets/Ruleset.cs | 9 +--- .../Screens/Select/Details/AdvancedStats.cs | 37 ++------------- 6 files changed, 152 insertions(+), 55 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index a63e604204..4f499cee62 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -233,8 +234,41 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm }; } - public override double PreemptFromAr(float AR) => AR < 5 ? (1200.0 + 600.0 * (5 - AR) / 5) : (1200.0 - 750.0 * (AR - 5) / 5); - public override float ArFromPreempt(double preempt) => (float)(preempt > 1200 ? ((1800 - preempt) / 120) : ((1200 - preempt) / 150)) + 5; - public override float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate); + public double PreemptFromAr(float AR) => AR < 5 ? (1200.0 + 600.0 * (5 - AR) / 5) : (1200.0 - 750.0 * (AR - 5) / 5); + public float ArFromPreempt(double preempt) => (float)(preempt > 1200 ? ((1800 - preempt) / 120) : ((1200 - preempt) / 150)) + 5; + public float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate); + + public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList mods, ref (bool AR, bool OD) isRateAdjusted) + { + BeatmapDifficulty? adjustedDifficulty = null; + isRateAdjusted = (false, false); + + if (mods.Any(m => m is IApplicableToDifficulty)) + { + adjustedDifficulty = new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + mod.ApplyToDifficulty(adjustedDifficulty); + } + + if (mods.Any(m => m is ModRateAdjust)) + { + adjustedDifficulty ??= new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + { + double speedChange = (float)mod.SpeedChange.Value; + + float ar = adjustedDifficulty.ApproachRate; + float od = adjustedDifficulty.OverallDifficulty; + + adjustedDifficulty.ApproachRate = ChangeArFromRate(ar, speedChange); + + if (adjustedDifficulty.ApproachRate != ar) isRateAdjusted.AR = true; + } + } + + return adjustedDifficulty ?? (BeatmapDifficulty)baseDifficulty; + } } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 181e932788..7d16806397 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -428,9 +428,41 @@ public override IRulesetFilterCriteria CreateRulesetFilterCriteria() public override DifficultySection CreateEditorDifficultySection() => new ManiaDifficultySection(); - public override double HitwindowFromOd(float OD) => 64.0 - 3 * OD; - public override float OdFromHitwindow(double hitwindow300) => (float)(64.0 - hitwindow300) / 3; - public override float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public double HitwindowFromOd(float OD) => 64.0 - 3 * OD; + public float OdFromHitwindow(double hitwindow300) => (float)(64.0 - hitwindow300) / 3; + public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList mods, ref (bool AR, bool OD) isRateAdjusted) + { + BeatmapDifficulty? adjustedDifficulty = null; + isRateAdjusted = (false, false); + + if (mods.Any(m => m is IApplicableToDifficulty)) + { + adjustedDifficulty = new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + mod.ApplyToDifficulty(adjustedDifficulty); + } + + if (mods.Any(m => m is ModRateAdjust)) + { + adjustedDifficulty ??= new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + { + double speedChange = (float)mod.SpeedChange.Value; + + float od = adjustedDifficulty.OverallDifficulty; + + adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange); + + if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true; + } + } + + return adjustedDifficulty ?? (BeatmapDifficulty)baseDifficulty; + } + } public enum PlayfieldType diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index fa575192c6..250685ec0f 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -329,11 +329,45 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm public override RulesetSetupSection CreateEditorSetupSection() => new OsuSetupSection(); - public override double PreemptFromAr(float AR) => AR < 5 ? (1200.0 + 600.0 * (5 - AR) / 5) : (1200.0 - 750.0 * (AR - 5) / 5); - public override float ArFromPreempt(double preempt) => (float)(preempt > 1200 ? ((1800 - preempt) / 120) : ((1200 - preempt) / 150)) + 5; - public override double HitwindowFromOd(float OD) => 80.0 - 6 * OD; - public override float OdFromHitwindow(double hitwindow300) => (float)(80.0 - hitwindow300) / 6; - public override float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate); - public override float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public double PreemptFromAr(float AR) => AR < 5 ? (1200.0 + 600.0 * (5 - AR) / 5) : (1200.0 - 750.0 * (AR - 5) / 5); + public float ArFromPreempt(double preempt) => (float)(preempt > 1200 ? ((1800 - preempt) / 120) : ((1200 - preempt) / 150)) + 5; + public double HitwindowFromOd(float OD) => 80.0 - 6 * OD; + public float OdFromHitwindow(double hitwindow300) => (float)(80.0 - hitwindow300) / 6; + public float ChangeArFromRate(float AR, double rate) => ArFromPreempt(PreemptFromAr(AR) / rate); + public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList mods, ref (bool AR, bool OD) isRateAdjusted) + { + BeatmapDifficulty? adjustedDifficulty = null; + isRateAdjusted = (false, false); + + if (mods.Any(m => m is IApplicableToDifficulty)) + { + adjustedDifficulty = new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + mod.ApplyToDifficulty(adjustedDifficulty); + } + + if (mods.Any(m => m is ModRateAdjust)) + { + adjustedDifficulty ??= new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + { + double speedChange = (float)mod.SpeedChange.Value; + + float ar = adjustedDifficulty.ApproachRate; + float od = adjustedDifficulty.OverallDifficulty; + + adjustedDifficulty.ApproachRate = ChangeArFromRate(ar, speedChange); + adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange); + + if (adjustedDifficulty.ApproachRate != ar) isRateAdjusted.AR = true; + if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true; + } + } + + return adjustedDifficulty ?? (BeatmapDifficulty)baseDifficulty; + } } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 23d732645e..801e46f9c3 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -263,8 +263,39 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm }), true) }; } - public override double HitwindowFromOd(float OD) => 35.0 - 15.0 * (OD - 5) / 5; - public override float OdFromHitwindow(double hitwindow300) => (float)(5 * (35 - hitwindow300) / 15 + 5); - public override float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public double HitwindowFromOd(float OD) => 35.0 - 15.0 * (OD - 5) / 5; + public float OdFromHitwindow(double hitwindow300) => (float)(5 * (35 - hitwindow300) / 15 + 5); + public float ChangeOdFromRate(float OD, double rate) => OdFromHitwindow(HitwindowFromOd(OD) / rate); + public override BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList mods, ref (bool AR, bool OD) isRateAdjusted) + { + BeatmapDifficulty? adjustedDifficulty = null; + isRateAdjusted = (false, false); + + if (mods.Any(m => m is IApplicableToDifficulty)) + { + adjustedDifficulty = new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + mod.ApplyToDifficulty(adjustedDifficulty); + } + + if (mods.Any(m => m is ModRateAdjust)) + { + adjustedDifficulty ??= new BeatmapDifficulty(baseDifficulty); + + foreach (var mod in mods.OfType()) + { + double speedChange = (float)mod.SpeedChange.Value; + + float od = adjustedDifficulty.OverallDifficulty; + + adjustedDifficulty.OverallDifficulty = ChangeOdFromRate(od, speedChange); + + if (adjustedDifficulty.OverallDifficulty != od) isRateAdjusted.OD = true; + } + } + + return adjustedDifficulty ?? (BeatmapDifficulty)baseDifficulty; + } } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ed4bc0ea7a..0f7655812a 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -389,13 +389,6 @@ protected Ruleset() /// Can be overridden to alter the difficulty section to the editor beatmap setup screen. /// public virtual DifficultySection? CreateEditorDifficultySection() => null; - - public virtual double PreemptFromAr(float AR) => 0; - public virtual float ArFromPreempt(double preempt) => 5; - public virtual double HitwindowFromOd(float OD) => 0; - public virtual float OdFromHitwindow(double hitwindow300) => 0; - - public virtual float ChangeArFromRate(float AR, double rate) => AR; - public virtual float ChangeOdFromRate(float OD, double rate) => OD; + public virtual BeatmapDifficulty GetEffectiveDifficulty(IBeatmapDifficultyInfo baseDifficulty, IReadOnlyList mods, ref (bool AR, bool OD) isRateAdjusted) => (BeatmapDifficulty)baseDifficulty; } } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 4b7eee380d..4a0eed86f8 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -15,7 +15,6 @@ using osu.Framework.Bindables; using System.Collections.Generic; using osu.Game.Rulesets.Mods; -using System.Linq; using System.Threading; using System.Threading.Tasks; using osu.Framework.Extensions; @@ -44,9 +43,6 @@ public partial class AdvancedStats : Container protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; private readonly StatisticRow starDifficulty; - private bool isArRateAdjusted { get; set; } - private bool isOdRateAdjusted { get; set; } - private IBeatmapInfo beatmapInfo; public IBeatmapInfo BeatmapInfo @@ -120,35 +116,12 @@ private void updateStatistics() { IBeatmapDifficultyInfo baseDifficulty = BeatmapInfo?.Difficulty; BeatmapDifficulty adjustedDifficulty = null; - isArRateAdjusted = false; - isOdRateAdjusted = false; + (bool AR, bool OD) isRateAdjusted = (false, false); - if (baseDifficulty != null && mods.Value.Any(m => m is IApplicableToDifficulty)) + if (baseDifficulty != null) { - adjustedDifficulty = new BeatmapDifficulty(baseDifficulty); - - foreach (var mod in mods.Value.OfType()) - mod.ApplyToDifficulty(adjustedDifficulty); - } - - if (baseDifficulty != null && mods.Value.Any(m => m is ModRateAdjust)) - { - adjustedDifficulty ??= new BeatmapDifficulty(baseDifficulty); Ruleset ruleset = gameRuleset.Value.CreateInstance(); - - foreach (var mod in mods.Value.OfType()) - { - double speedChange = (float)mod.SpeedChange.Value; - - float ar = adjustedDifficulty.ApproachRate; - float od = adjustedDifficulty.OverallDifficulty; - - adjustedDifficulty.ApproachRate = ruleset.ChangeArFromRate(ar, speedChange); - adjustedDifficulty.OverallDifficulty = ruleset.ChangeOdFromRate(od, speedChange); - - if (adjustedDifficulty.ApproachRate != ar) isArRateAdjusted = true; - if (adjustedDifficulty.OverallDifficulty != od) isOdRateAdjusted = true; - } + adjustedDifficulty = ruleset.GetEffectiveDifficulty(baseDifficulty, mods.Value, ref isRateAdjusted); } switch (BeatmapInfo?.Ruleset.OnlineID) @@ -167,8 +140,8 @@ private void updateStatistics() } HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate, false); - Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty, isOdRateAdjusted); - ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate, isArRateAdjusted); + Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty, isRateAdjusted.OD); + ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate, isRateAdjusted.AR); updateStarDifficulty(); }