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.