mirror of
https://github.com/ppy/osu.git
synced 2025-02-23 18:23:17 +08:00
Fix distance snap grid colours being off-by-one in certain cases
Closes https://github.com/ppy/osu/issues/31909. Previously: https://github.com/ppy/osu/pull/30062. Happening because of rounding errors - in this case the beat index pre-flooring was something like a 0.003 off of a full beat, which would get floored down rather than rounded up which created the discrepancy. But also we don't want to round *too* far, which is why this frankenstein solution has to exist I think. This is probably all exacerbated by stable not handling decimal control point start times. Would add tests if not for the fact that this is like extremely annoying to test.
This commit is contained in:
parent
282039f0a8
commit
8423d9de9b
@ -11,6 +11,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@ -148,7 +149,18 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
var timingPoint = Beatmap.ControlPointInfo.TimingPointAt(StartTime);
|
||||
double beatLength = timingPoint.BeatLength / beatDivisor.Value;
|
||||
int beatIndex = (int)Math.Floor((StartTime - timingPoint.Time) / beatLength);
|
||||
double fractionalBeatIndex = (StartTime - timingPoint.Time) / beatLength;
|
||||
int beatIndex = (int)Math.Round(fractionalBeatIndex);
|
||||
// `fractionalBeatIndex` could differ from `beatIndex` for two reasons:
|
||||
// - rounding errors (which can be exacerbated by timing point start times being truncated by/for stable),
|
||||
// - `StartTime` is not snapped to the beat.
|
||||
// in case 1, we want rounding to occur to prevent an off-by-one,
|
||||
// as `StartTime` *is* quantised to the beat. but it just doesn't look like it because floats do float things.
|
||||
// in case 2, we want *flooring* to occur, to prevent a possible off-by-one
|
||||
// because of the rounding snapping forward by a chunk of time significantly too high to be considered a rounding error.
|
||||
// the tolerance margin chosen here is arbitrary and can be adjusted if more cases of this are found.
|
||||
if (Precision.DefinitelyBigger(beatIndex, fractionalBeatIndex, 0.005))
|
||||
beatIndex = (int)Math.Floor(fractionalBeatIndex);
|
||||
|
||||
var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(beatIndex + placementIndex + 1, beatDivisor.Value), Colours);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user