// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Judgements { public class HitWindows { #region Constants /// /// PERFECT hit window at OD = 10. /// private const double perfect_min = 27.8; /// /// PERFECT hit window at OD = 5. /// private const double perfect_mid = 38.8; /// /// PERFECT hit window at OD = 0. /// private const double perfect_max = 44.8; /// /// GREAT hit window at OD = 10. /// private const double great_min = 68; /// /// GREAT hit window at OD = 5. /// private const double great_mid = 98; /// /// GREAT hit window at OD = 0. /// private const double great_max = 128; /// /// GOOD hit window at OD = 10. /// private const double good_min = 134; /// /// GOOD hit window at OD = 5. /// private const double good_mid = 164; /// /// GOOD hit window at OD = 0. /// private const double good_max = 194; /// /// OK hit window at OD = 10. /// private const double ok_min = 194; /// /// OK hit window at OD = 5. /// private const double ok_mid = 224; /// /// OK hit window at OD = 0. /// private const double ok_max = 254; /// /// BAD hit window at OD = 10. /// private const double bad_min = 242; /// /// BAD hit window at OD = 5. /// private const double bad_mid = 272; /// /// BAD hit window at OD = 0. /// private const double bad_max = 302; /// /// MISS hit window at OD = 10. /// private const double miss_min = 316; /// /// MISS hit window at OD = 5. /// private const double miss_mid = 346; /// /// MISS hit window at OD = 0. /// private const double miss_max = 376; #endregion /// /// Hit window for a PERFECT hit. /// public double Perfect = perfect_mid; /// /// Hit window for a GREAT hit. /// public double Great = great_mid; /// /// Hit window for a GOOD hit. /// public double Good = good_mid; /// /// Hit window for an OK hit. /// public double Ok = ok_mid; /// /// Hit window for a BAD hit. /// public double Bad = bad_mid; /// /// Hit window for a MISS hit. /// public double Miss = miss_mid; /// /// Constructs default hit windows. /// public HitWindows() { } /// /// Constructs hit windows by fitting a parameter to a 2-part piecewise linear function for each hit window. /// /// The parameter. public HitWindows(double difficulty) { Perfect = BeatmapDifficulty.DifficultyRange(difficulty, perfect_max, perfect_mid, perfect_min); Great = BeatmapDifficulty.DifficultyRange(difficulty, great_max, great_mid, great_min); Good = BeatmapDifficulty.DifficultyRange(difficulty, good_max, good_mid, good_min); Ok = BeatmapDifficulty.DifficultyRange(difficulty, ok_max, ok_mid, ok_min); Bad = BeatmapDifficulty.DifficultyRange(difficulty, bad_max, bad_mid, bad_min); Miss = BeatmapDifficulty.DifficultyRange(difficulty, miss_max, miss_mid, miss_min); } /// /// Retrieves the hit result for a time offset. /// /// The time offset. /// The hit result, or null if the time offset results in a miss. public HitResult? ResultFor(double hitOffset) { if (hitOffset <= Perfect / 2) return HitResult.Perfect; if (hitOffset <= Great / 2) return HitResult.Great; if (hitOffset <= Good / 2) return HitResult.Good; if (hitOffset <= Ok / 2) return HitResult.Ok; if (hitOffset <= Bad / 2) return HitResult.Meh; return null; } /// /// Constructs new hit windows which have been multiplied by a value. /// /// The original hit windows. /// The value to multiply each hit window by. public static HitWindows operator *(HitWindows windows, double value) { return new HitWindows { Perfect = windows.Perfect * value, Great = windows.Great * value, Good = windows.Good * value, Ok = windows.Ok * value, Bad = windows.Bad * value, Miss = windows.Miss * value }; } /// /// Constructs new hit windows which have been divided by a value. /// /// The original hit windows. /// The value to divide each hit window by. public static HitWindows operator /(HitWindows windows, double value) { return new HitWindows { Perfect = windows.Perfect / value, Great = windows.Great / value, Good = windows.Good / value, Ok = windows.Ok / value, Bad = windows.Bad / value, Miss = windows.Miss / value }; } } }