// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using System; using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing; using osu.Game.Rulesets.Taiko.Difficulty.Skills; using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Scoring; namespace osu.Game.Rulesets.Taiko.Difficulty { public class TaikoDifficultyCalculator : DifficultyCalculator { private const double difficulty_multiplier = 1.9; public TaikoDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap) : base(ruleset, beatmap) { } protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) { return new Skill[] { new Peaks(mods, beatmap) }; } protected override Mod[] DifficultyAdjustmentMods => new Mod[] { new TaikoModDoubleTime(), new TaikoModHalfTime(), new TaikoModEasy(), new TaikoModHardRock(), }; protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) { return TaikoDifficultyHitObject.Create(beatmap, clockRate); } protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) { if (beatmap.HitObjects.Count == 0) return new TaikoDifficultyAttributes { Mods = mods }; var combined = (Peaks)skills[0]; double colourRating = Math.Sqrt(combined.ColourDifficultyValue * difficulty_multiplier); double rhythmRating = Math.Sqrt(combined.RhythmDifficultyValue * difficulty_multiplier); double staminaRating = Math.Sqrt(combined.StaminaDifficultyValue * difficulty_multiplier); double combinedRating = combined.DifficultyValue(); double starRating = rescale(combinedRating * difficulty_multiplier); HitWindows hitWindows = new TaikoHitWindows(); hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty); return new TaikoDifficultyAttributes { StarRating = starRating, Mods = mods, StaminaDifficulty = staminaRating, RhythmDifficulty = rhythmRating, ColourDifficulty = colourRating, PeakDifficulty = combinedRating, GreatHitWindow = hitWindows.WindowFor(HitResult.Great) / clockRate, MaxCombo = beatmap.HitObjects.Count(h => h is Hit), }; } /// /// Applies a final re-scaling of the star rating to bring maps with recorded full combos below 9.5 stars. /// /// The raw star rating value before re-scaling. private double rescale(double sr) { if (sr < 0) return sr; return 10.43 * Math.Log(sr / 8 + 1); } } }