Closes https://github.com/ppy/osu/issues/25608.
Logic mostly matching stable. All operations are done on `ComboOffset`
which still makes overridden combo colours weirdly relatively dependent
on each other rather than them be an "absolute" choice, but alas...
As per stable, two consecutive new combos can use the same colour only
if they are separated by a break:
52f3f75ed7/osu!/GameModes/Edit/Modes/EditorModeCompose.cs#L4564-L4571
This control is only available once the user has changed the combo
colours from defaults; additionally, only a single new combo object
must be selected for the colour selector to show up.
RFC. This closes https://github.com/ppy/osu/issues/31186.
To explain why: The issue occurs on
https://osu.ppy.sh/beatmapsets/594828#osu/1258033, specifically on the
slider at time 128604. The failure site is
fa0d2f4af2/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleOverlay.cs (L65-L66)
wherein `LastRepeat` is `null`, even though the slider's `RepeatCount`
is 1 and thus `SpanCount` is 2.
In this case, `SliderEventGenerator` is given a non-zero `tickDistance`
but a zero `length`. The former is clamped to the latter:
fa0d2f4af2/osu.Game/Rulesets/Objects/SliderEventGenerator.cs (L34)
Because of this, a whole block of code pertaining to tick generation
gets turned off, because of zero tick spacing - however, that block also
includes within it *repeat* generation, for seemingly very little reason
whatsoever:
fa0d2f4af2/osu.Game/Rulesets/Objects/SliderEventGenerator.cs (L47-L77)
While a zero tick distance would indeed cause `generateTicks()` to loop
forever, it should have absolutely no effect on repeats.
While this *is* ultimately an aspire-tier bug caused by people pushing
things to limits, I do believe that in this case a fix is warranted
because of how hard the current behaviour violates invariants. I do not
like the possibility of having a slider with multiple spans and no
repeats.
Having these be separate implementations sounded awesome at the time,
but it only ever led to confusion. There's no practical difference if,
for example, catch sees hitobjects with `IHasPosition` instead of
`IHasXPosition`.