mirror of
https://github.com/ppy/osu.git
synced 2026-05-22 16:10:24 +08:00
8b542e5442
This change pulls back a significant degree of overspecialisation and rigidity in the class structure of `HitWindows` to make subsequent changes to hit windows, whose purpose is to improve replay playback accuracy, possible to do cleanly. Notably: - `HitWindows` is full abstract now. In a few use cases, and as a reference for ruleset implementors, `DefaultHitWindows` is provided as a separate class instead. This fixes the weirdness wherein `HitWindows` always declared 6 fields for result types but some of them would never be set to a non-zero value or read. - `HitWindow.GetRanges()` is deleted because it is overspecialised and prevents being able to adjust hitwindows by ±0.5ms cleanly which will be required later. The fallout of this is that the assertion that used `GetRanges()` in the `HitWindows` ctor must use something else now, and the closest thing to it was `GetAllAvailableWindows()`, which didn't return the miss window - so I made it return the miss window and fixed the one consumer that didn't want it (bar hit error meter) to skip it. - Diff also contains some clean-up around `DifficultyRange` to unify handling of it.
68 lines
2.1 KiB
C#
68 lines
2.1 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
using System;
|
|
using osu.Game.Beatmaps;
|
|
using osu.Game.Rulesets.Scoring;
|
|
|
|
namespace osu.Game.Rulesets.Osu.Scoring
|
|
{
|
|
public class OsuHitWindows : HitWindows
|
|
{
|
|
public static readonly DifficultyRange GREAT_WINDOW_RANGE = new DifficultyRange(80, 50, 20);
|
|
public static readonly DifficultyRange OK_WINDOW_RANGE = new DifficultyRange(140, 100, 60);
|
|
public static readonly DifficultyRange MEH_WINDOW_RANGE = new DifficultyRange(200, 150, 100);
|
|
|
|
/// <summary>
|
|
/// osu! ruleset has a fixed miss window regardless of difficulty settings.
|
|
/// </summary>
|
|
public const double MISS_WINDOW = 400;
|
|
|
|
private double great;
|
|
private double ok;
|
|
private double meh;
|
|
|
|
public override bool IsHitResultAllowed(HitResult result)
|
|
{
|
|
switch (result)
|
|
{
|
|
case HitResult.Great:
|
|
case HitResult.Ok:
|
|
case HitResult.Meh:
|
|
case HitResult.Miss:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override void SetDifficulty(double difficulty)
|
|
{
|
|
great = IBeatmapDifficultyInfo.DifficultyRange(difficulty, GREAT_WINDOW_RANGE);
|
|
ok = IBeatmapDifficultyInfo.DifficultyRange(difficulty, OK_WINDOW_RANGE);
|
|
meh = IBeatmapDifficultyInfo.DifficultyRange(difficulty, MEH_WINDOW_RANGE);
|
|
}
|
|
|
|
public override double WindowFor(HitResult result)
|
|
{
|
|
switch (result)
|
|
{
|
|
case HitResult.Great:
|
|
return great;
|
|
|
|
case HitResult.Ok:
|
|
return ok;
|
|
|
|
case HitResult.Meh:
|
|
return meh;
|
|
|
|
case HitResult.Miss:
|
|
return MISS_WINDOW;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException(nameof(result), result, null);
|
|
}
|
|
}
|
|
}
|
|
}
|