1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-22 16:10:24 +08:00
Files
osu-lazer/osu.Game.Rulesets.Osu/Scoring/OsuHitWindows.cs
T
Bartłomiej Dach 8b542e5442 Refactor hit windows class structure to reduce rigidity
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.
2025-06-25 08:40:12 +02:00

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);
}
}
}
}