diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ReadingEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ReadingEvaluator.cs
index 58719796133f..0c9c25b630ab 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ReadingEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ReadingEvaluator.cs
@@ -2,8 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Linq;
using osu.Game.Rulesets.Difficulty.Utils;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Taiko.Mods;
namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
{
@@ -25,32 +28,143 @@ public VelocityRange(double min, double max)
///
/// Calculates the influence of higher slider velocities on hitobject difficulty.
- /// The bonus is determined based on the EffectiveBPM, shifting within a defined range
- /// between the upper and lower boundaries to reflect how increased slider velocity impacts difficulty.
+ /// The bonus is determined based on the EffectiveBPM, object density and the effects of mods.
///
/// The hit object to evaluate.
+ /// The mods which were applied to the beatmap.
/// The reading difficulty value for the given hit object.
- public static double EvaluateDifficultyOf(TaikoDifficultyHitObject noteObject)
+ public static double EvaluateDifficultyOf(TaikoDifficultyHitObject noteObject, Mod[] mods, bool isHidden)
{
- var highVelocity = new VelocityRange(480, 640);
- var midVelocity = new VelocityRange(360, 480);
+ bool isFlashlight = mods.Any(m => m is TaikoModFlashlight);
- // Apply a cap to prevent outlier values on maps that exceed the editor's parameters.
- double effectiveBPM = Math.Max(1.0, noteObject.EffectiveBPM);
+ // With HDFL, all note objects are invisible and give the maximum reading difficulty
+ if (isHidden && isFlashlight)
+ return 1.0;
- double midVelocityDifficulty = 0.5 * DifficultyCalculationUtils.Logistic(effectiveBPM, midVelocity.Center, 1.0 / (midVelocity.Range / 10));
+ double velocityDifficulty = calculateVelocityDifficulty(noteObject, mods, isHidden);
+ double densityDifficulty = calculateDensityDifficulty(noteObject);
- // Expected DeltaTime is the DeltaTime this note would need to be spaced equally to a base slider velocity 1/4 note.
- double expectedDeltaTime = 21000.0 / effectiveBPM;
- double objectDensity = expectedDeltaTime / Math.Max(1.0, noteObject.DeltaTime);
+ double difficulty = Math.Max(velocityDifficulty, densityDifficulty);
+
+ // With hidden, all notes award a base difficulty
+ if (isHidden)
+ difficulty = 0.25 + 0.75 * difficulty;
+
+ return difficulty;
+ }
+
+ private static double calculateVelocityDifficulty(TaikoDifficultyHitObject noteObject, Mod[] mods, bool isHidden)
+ {
+ double highVelocityDifficulty = 0.0;
+ double timeInvisibleDifficulty = 0.0;
+
+ // To allow high velocity sections at lower actual BPM to award similar difficulty to high BPM sections with more frequent objects,
+ // a bonus is applied to the high velocity range at lower object density
+ double densityBonus = calculateHighVelocityDensityBonus(noteObject);
+
+ var highVelocity = new VelocityRange(
+ 420 - 140 * densityBonus,
+ 1000 - 320 * densityBonus
+ );
+
+ highVelocityDifficulty = DifficultyCalculationUtils.Logistic(
+ noteObject.EffectiveBPM * calculateHighVelocityModMultiplier(mods, isHidden),
+ highVelocity.Center,
+ 10.0 / highVelocity.Range
+ );
+
+ // With hidden, notes that stay invisible for longer before being hit are harder to read
+ if (isHidden) {
+ var lowVelocity = new VelocityRange(280, 125);
+
+ timeInvisibleDifficulty = DifficultyCalculationUtils.Logistic(
+ noteObject.EffectiveBPM * calculateTimeInvisibleModMultiplier(mods),
+ lowVelocity.Center,
+ 10.0 / lowVelocity.Range
+ );
+ }
+
+ return Math.Max(highVelocityDifficulty, timeInvisibleDifficulty);
+ }
+
+ private static double calculateHighVelocityDensityBonus(TaikoDifficultyHitObject noteObject)
+ {
+ double density = calculateObjectDensity(noteObject);
+
+ // Single note gaps in otherwise dense sections would overly award the bonus for low density
+ // As a result, the higher density out of both the current and previous note is used
+ var prevNoteObject = (TaikoDifficultyHitObject) noteObject.Previous(0);
+
+ if (prevNoteObject != null)
+ {
+ double prevDensity = calculateObjectDensity(prevNoteObject);
+ return DifficultyCalculationUtils.Smoothstep(Math.Max(density, prevDensity), 0.9, 0.35);
+ }
+
+ return DifficultyCalculationUtils.Smoothstep(density, 0.9, 0.35);
+ }
+
+ private static double calculateHighVelocityModMultiplier(Mod[] mods, bool isHidden)
+ {
+ bool isFlashlight = mods.Any(m => m is TaikoModFlashlight);
+ bool isEasy = mods.Any(m => m is TaikoModEasy);
- // High density is penalised at high velocity as it is generally considered easier to read. See https://www.desmos.com/calculator/u63f3ntdsi
- double densityPenalty = DifficultyCalculationUtils.Logistic(objectDensity, 0.925, 15);
+ double multiplier = 1.0;
+
+ if (isHidden)
+ {
+ // With hidden enabled, the playfield is limited from the expected 1560px wide (equivalent to 16:9) to only 1080px (4:3)
+ // This is not the case with the classic mod enabled, but due to current limitations this is penalised in performance calculation instead
+ // Considerations for HDHRCL are currently out of scope
+ multiplier *= 1560.0 / 1080.0;
+
+ // Notes fading out after a short time with hidden means their velocity is essentially higher. With easy enabled, notes fade out after longer.
+ // Both of these values are arbitrary and based on feedback
+ if (isEasy)
+ multiplier *= 1.1;
+ else
+ multiplier *= 1.2;
+ }
+
+ // With flashlight, the visible playfield is limited from the expected 1560px wide to around 468px
+ // Considerations for combo and smaller flashlights are currently out of scope
+ if (isFlashlight)
+ multiplier *= 1560.0 / 468.0;
+
+ return multiplier;
+ }
+
+ private static double calculateTimeInvisibleModMultiplier(Mod[] mods)
+ {
+ bool isEasy = mods.Any(m => m is TaikoModEasy);
- double highVelocityDifficulty = (1.0 - 0.33 * densityPenalty)
- * DifficultyCalculationUtils.Logistic(effectiveBPM, highVelocity.Center + 8 * densityPenalty, (1.0 + 0.5 * densityPenalty) / (highVelocity.Range / 10));
+ double multiplier = 1.0;
+
+ // With easy enabled, notes fade out later and are invisible for less time. This is equivalent to their effective BPM being higher
+ if (isEasy)
+ multiplier *= 1.35;
+
+ return multiplier;
+ }
+
+ private static double calculateDensityDifficulty(TaikoDifficultyHitObject noteObject)
+ {
+ // Notes at very high density are harder to read
+ return Math.Pow(
+ DifficultyCalculationUtils.Logistic(calculateObjectDensity(noteObject), 3.5, 1.5),
+ 3.0
+ );
+ }
+
+ private static double calculateObjectDensity(TaikoDifficultyHitObject noteObject)
+ {
+ if (noteObject.EffectiveBPM == 0 || noteObject.DeltaTime == 0)
+ return 1.0;
+
+ // Expected DeltaTime is the DeltaTime this note would need to be spaced equally to a base slider velocity 1/4 note.
+ double expectedDeltaTime = 21000.0 / noteObject.EffectiveBPM;
- return midVelocityDifficulty + highVelocityDifficulty;
+ return expectedDeltaTime / noteObject.DeltaTime;
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Reading.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Reading.cs
index 7be1107b7042..7e907b2ea602 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Reading.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Reading.cs
@@ -1,12 +1,14 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Difficulty.Utils;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Difficulty.Evaluators;
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Taiko.Mods;
using osu.Game.Rulesets.Taiko.Objects;
namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
@@ -21,9 +23,14 @@ public class Reading : StrainDecaySkill
private double currentStrain;
- public Reading(Mod[] mods)
+ private Mod[] mods;
+ public readonly bool HiddenDifficultyOnly;
+
+ public Reading(Mod[] mods, bool HiddenDifficultyOnly)
: base(mods)
{
+ this.mods = mods;
+ this.HiddenDifficultyOnly = HiddenDifficultyOnly;
}
protected override double StrainValueOf(DifficultyHitObject current)
@@ -34,13 +41,29 @@ protected override double StrainValueOf(DifficultyHitObject current)
return 0.0;
}
+ bool isHidden = mods.Any(m => m is TaikoModHidden);
+
var taikoObject = (TaikoDifficultyHitObject)current;
int index = taikoObject.ColourData.MonoStreak?.HitObjects.IndexOf(taikoObject) ?? 0;
currentStrain *= DifficultyCalculationUtils.Logistic(index, 4, -1 / 25.0, 0.5) + 0.5;
-
currentStrain *= StrainDecayBase;
- currentStrain += ReadingEvaluator.EvaluateDifficultyOf(taikoObject) * SkillMultiplier;
+
+ double difficulty = ReadingEvaluator.EvaluateDifficultyOf(taikoObject, mods, isHidden);
+
+ if (HiddenDifficultyOnly)
+ {
+ double hiddenDifficulty = 0.0;
+
+ if (isHidden)
+ hiddenDifficulty = difficulty - ReadingEvaluator.EvaluateDifficultyOf(taikoObject, mods, false);
+
+ currentStrain += hiddenDifficulty * SkillMultiplier;
+ }
+ else
+ {
+ currentStrain += difficulty * SkillMultiplier;
+ }
return currentStrain;
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs
index c5cc04449cd6..b1b264fbbe43 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs
@@ -25,8 +25,15 @@ public class TaikoDifficultyAttributes : DifficultyAttributes
///
/// The difficulty corresponding to the reading skill.
///
+ [JsonProperty("reading_difficulty")]
public double ReadingDifficulty { get; set; }
+ ///
+ /// Contribution to reading difficulty from the hidden mod.
+ ///
+ [JsonProperty("hidden_reading_difficulty")]
+ public double HiddenReadingDifficulty { get; set; }
+
///
/// The difficulty corresponding to the colour skill.
///
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
index 64af2861eca2..aee630981c29 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
@@ -23,12 +23,13 @@ public class TaikoDifficultyCalculator : DifficultyCalculator
{
private const double difficulty_multiplier = 0.084375;
private const double rhythm_skill_multiplier = 0.750 * difficulty_multiplier;
- private const double reading_skill_multiplier = 0.100 * difficulty_multiplier;
+ private const double reading_skill_multiplier = 0.200 * difficulty_multiplier;
private const double colour_skill_multiplier = 0.375 * difficulty_multiplier;
private const double stamina_skill_multiplier = 0.445 * difficulty_multiplier;
private double strainLengthBonus;
private double patternMultiplier;
+ private double readingLengthPenalty;
private bool isRelax;
private bool isConvert;
@@ -48,7 +49,8 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods)
return new Skill[]
{
new Rhythm(mods),
- new Reading(mods),
+ new Reading(mods, false),
+ new Reading(mods, true),
new Colour(mods),
new Stamina(mods, false, isConvert),
new Stamina(mods, true, isConvert)
@@ -61,6 +63,7 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods)
new TaikoModHalfTime(),
new TaikoModEasy(),
new TaikoModHardRock(),
+ new TaikoModHidden(),
};
protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods)
@@ -101,27 +104,34 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
return new TaikoDifficultyAttributes { Mods = mods };
var rhythm = skills.OfType().Single();
- var reading = skills.OfType().Single();
+ var reading = skills.OfType().Single(s => !s.HiddenDifficultyOnly);
+ var hiddenReading = skills.OfType().Single(s => s.HiddenDifficultyOnly);
var colour = skills.OfType().Single();
var stamina = skills.OfType().Single(s => !s.SingleColourStamina);
var singleColourStamina = skills.OfType().Single(s => s.SingleColourStamina);
double staminaDifficultyValue = stamina.DifficultyValue();
+ double readingDifficultyValue = reading.DifficultyValue();
double rhythmSkill = rhythm.DifficultyValue() * rhythm_skill_multiplier;
double readingSkill = reading.DifficultyValue() * reading_skill_multiplier;
+ double hiddenReadingSkill = hiddenReading.DifficultyValue() * reading_skill_multiplier;
double colourSkill = colour.DifficultyValue() * colour_skill_multiplier;
double staminaSkill = staminaDifficultyValue * stamina_skill_multiplier;
double monoStaminaSkill = singleColourStamina.DifficultyValue() * stamina_skill_multiplier;
double monoStaminaFactor = staminaSkill == 0 ? 1 : Math.Pow(monoStaminaSkill / staminaSkill, 5);
double staminaDifficultStrains = stamina.CountTopWeightedStrains(staminaDifficultyValue);
+ double readingDifficultStrains = reading.CountTopWeightedStrains(readingDifficultyValue);
// As we don't have pattern integration in osu!taiko, we apply the other two skills relative to rhythm.
patternMultiplier = Math.Pow(staminaSkill * colourSkill, 0.10);
strainLengthBonus = 1 + 0.15 * DifficultyCalculationUtils.ReverseLerp(staminaDifficultStrains, 1000, 1555);
+ // Apply a penalty to small amounts of reading that can be memorised.
+ readingLengthPenalty = DifficultyCalculationUtils.ReverseLerp(readingDifficultStrains, 0, 150);
+
double combinedRating = combinedDifficultyValue(rhythm, reading, colour, stamina, out double consistencyFactor);
double starRating = rescale(combinedRating * 1.4);
@@ -130,6 +140,7 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
double rhythmDifficulty = rhythmSkill * skillRating;
double readingDifficulty = readingSkill * skillRating;
+ double hiddenReadingDifficulty = hiddenReadingSkill * skillRating;
double colourDifficulty = colourSkill * skillRating;
double staminaDifficulty = staminaSkill * skillRating;
double mechanicalDifficulty = colourDifficulty + staminaDifficulty; // Mechanical difficulty is the sum of colour and stamina difficulties.
@@ -141,6 +152,7 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
MechanicalDifficulty = mechanicalDifficulty,
RhythmDifficulty = rhythmDifficulty,
ReadingDifficulty = readingDifficulty,
+ HiddenReadingDifficulty = hiddenReadingDifficulty,
ColourDifficulty = colourDifficulty,
StaminaDifficulty = staminaDifficulty,
MonoStaminaFactor = monoStaminaFactor,
@@ -216,7 +228,7 @@ private List combinePeaks(IReadOnlyList rhythmPeaks, IReadOnlyLi
for (int i = 0; i < colourPeaks.Count; i++)
{
double rhythmPeak = rhythmPeaks[i] * rhythm_skill_multiplier * patternMultiplier;
- double readingPeak = readingPeaks[i] * reading_skill_multiplier;
+ double readingPeak = readingPeaks[i] * reading_skill_multiplier * readingLengthPenalty;
double colourPeak = isRelax ? 0 : colourPeaks[i] * colour_skill_multiplier; // There is no colour difficulty in relax.
double staminaPeak = staminaPeaks[i] * stamina_skill_multiplier * strainLengthBonus;
staminaPeak /= isConvert || isRelax ? 1.5 : 1.0; // Available finger count is increased by 150%, thus we adjust accordingly.
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
index df9da49c4b80..a0190dbb3c2b 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
@@ -82,25 +82,12 @@ private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes
if (estimatedUnstableRate == null || totalDifficultHits == 0)
return 0;
- // The estimated unstable rate for 100% accuracy, at which all rhythm difficulty has been played successfully.
- double rhythmExpectedUnstableRate = computeDeviationUpperBound(1.0) * 10;
+ double penalisedStarRating = attributes.StarRating * calculateImproperlyPlayedRhythmPenalty(attributes.RhythmDifficulty, attributes.StarRating);
- // The unstable rate at which it can be assumed all rhythm difficulty has been ignored.
- // 0.8 represents 80% of total hits being greats, or 90% accuracy in-game
- double rhythmMaximumUnstableRate = computeDeviationUpperBound(0.8) * 10;
+ if (!isClassic)
+ penalisedStarRating *= calculateLazerHiddenReadingPenalty(attributes.HiddenReadingDifficulty, attributes.StarRating);
- // The fraction of star rating made up by rhythm difficulty, normalised to represent rhythm's perceived contribution to star rating.
- double rhythmFactor = DifficultyCalculationUtils.ReverseLerp(attributes.RhythmDifficulty / attributes.StarRating, 0.15, 0.4);
-
- // A penalty removing improperly played rhythm difficulty from star rating based on estimated unstable rate.
- double rhythmPenalty = 1 - DifficultyCalculationUtils.Logistic(
- estimatedUnstableRate.Value,
- midpointOffset: (rhythmExpectedUnstableRate + rhythmMaximumUnstableRate) / 2,
- multiplier: 10 / (rhythmMaximumUnstableRate - rhythmExpectedUnstableRate),
- maxValue: 0.25 * Math.Pow(rhythmFactor, 3)
- );
-
- double baseDifficulty = 5 * Math.Max(1.0, attributes.StarRating * rhythmPenalty / 0.110) - 4.0;
+ double baseDifficulty = 5 * Math.Max(1.0, penalisedStarRating / 0.110) - 4.0;
double difficultyValue = Math.Min(Math.Pow(baseDifficulty, 3) / 69052.51, Math.Pow(baseDifficulty, 2.25) / 1250.0);
difficultyValue *= 1 + 0.10 * Math.Max(0, attributes.StarRating - 10);
@@ -113,33 +100,41 @@ private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes
double missPenalty = 0.97 + 0.03 * totalDifficultHits / (totalDifficultHits + 1500);
difficultyValue *= Math.Pow(missPenalty, countMiss);
- if (score.Mods.Any(m => m is ModHidden))
- {
- double hiddenBonus = isConvert ? 0.025 : 0.1;
+ // Scale accuracy more harshly on nearly-completely mono (single coloured) speed maps.
+ double monoAccScalingExponent = 2 + attributes.MonoStaminaFactor;
+ double monoAccScalingShift = 500 - 100 * (attributes.MonoStaminaFactor * 3);
+
+ return difficultyValue * Math.Pow(DifficultyCalculationUtils.Erf(monoAccScalingShift / (Math.Sqrt(2) * estimatedUnstableRate.Value)), monoAccScalingExponent);
+ }
- // Hidden+flashlight plays are excluded from reading-based penalties to hidden.
- if (!score.Mods.Any(m => m is ModFlashlight))
- {
- // A penalty is applied to the bonus for hidden on non-classic scores, as the playfield can be made wider to make fast reading easier.
- if (!isClassic)
- hiddenBonus *= 0.2;
+ // A penalty removing improperly played rhythm difficulty from star rating based on estimated unstable rate.
+ private double calculateImproperlyPlayedRhythmPenalty(double rhythmDifficulty, double starRating)
+ {
+ // The estimated unstable rate for 100% accuracy, at which all rhythm difficulty has been played successfully.
+ double rhythmExpectedUnstableRate = computeDeviationUpperBound(1.0) * 10;
- // A penalty is applied to classic easy+hidden scores, as notes disappear later making fast reading easier.
- if (score.Mods.Any(m => m is ModEasy) && isClassic)
- hiddenBonus *= 0.5;
- }
+ // The unstable rate at which it can be assumed all rhythm difficulty has been ignored.
+ // 0.8 represents 80% of total hits being greats, or 90% accuracy in-game
+ double rhythmMaximumUnstableRate = computeDeviationUpperBound(0.8) * 10;
- difficultyValue *= 1 + hiddenBonus;
- }
+ // The fraction of star rating made up by rhythm difficulty, normalised to represent rhythm's perceived contribution to star rating.
+ double rhythmFactor = DifficultyCalculationUtils.ReverseLerp(rhythmDifficulty / starRating, 0.15, 0.4);
- if (score.Mods.Any(m => m is ModFlashlight))
- difficultyValue *= Math.Max(1, 1.050 - Math.Min(attributes.MonoStaminaFactor / 50, 1) * lengthBonus);
+ return 1 - DifficultyCalculationUtils.Logistic(
+ estimatedUnstableRate.Value,
+ midpointOffset: (rhythmExpectedUnstableRate + rhythmMaximumUnstableRate) / 2,
+ multiplier: 10 / (rhythmMaximumUnstableRate - rhythmExpectedUnstableRate),
+ maxValue: 0.25 * Math.Pow(rhythmFactor, 3)
+ );
+ }
- // Scale accuracy more harshly on nearly-completely mono (single coloured) speed maps.
- double monoAccScalingExponent = 2 + attributes.MonoStaminaFactor;
- double monoAccScalingShift = 500 - 100 * (attributes.MonoStaminaFactor * 3);
+ // A penalty removing hidden reading difficulty unfairly awarded by playing on lazer from star rating.
+ private double calculateLazerHiddenReadingPenalty(double hiddenDifficulty, double starRating)
+ {
+ // The fraction of star rating made up by hidden reading difficulty, normalised to represent hidden reading's perceived contribution to star rating.
+ double hiddenFactor = DifficultyCalculationUtils.ReverseLerp(hiddenDifficulty / starRating, 0.1, 0.35);
- return difficultyValue * Math.Pow(DifficultyCalculationUtils.Erf(monoAccScalingShift / (Math.Sqrt(2) * estimatedUnstableRate.Value)), monoAccScalingExponent);
+ return 1 - 0.15 * Math.Pow(hiddenFactor, 1.5);
}
private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert)
@@ -152,18 +147,12 @@ private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes a
// Scales up the bonus for lower unstable rate as star rating increases.
accuracyValue *= 1 + Math.Pow(50 / estimatedUnstableRate.Value, 2) * Math.Pow(attributes.StarRating, 2.8) / 600;
- if (score.Mods.Any(m => m is ModHidden) && !isConvert)
- accuracyValue *= 1.075;
+ if (score.Mods.Any(m => m is ModHidden))
+ accuracyValue *= 1.1;
// Applies a bonus to maps with more total difficulty, calculating this with a map's total hits and consistency factor.
accuracyValue *= 1 + 0.3 * totalDifficultHits / (totalDifficultHits + 4000);
- // Applies a bonus to maps with more total memory required with HDFL.
- double memoryLengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
-
- if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && !isConvert)
- accuracyValue *= Math.Max(1.0, 1.05 * memoryLengthBonus);
-
return accuracyValue;
}