Fixes https://github.com/ppy/osu/issues/29223
This fixes several issues around hold note dimming.
Notice in the following video:
- The tail piece of the first note not getting dimmed.
- The body of the second note not responding to dimming at all.
https://github.com/user-attachments/assets/8e51053d-8d88-4e48-909b-79218d65917b
Then, notice in the following video:
- The body piece of the second note is dimmed from the very beginning.
https://github.com/user-attachments/assets/a514c630-5c72-4ba5-96d5-472bae1058b3
This requires a specific setup whereby the hold note and its components
must be reused from the pool. In particular:
1. The hold note must be long. So long that by the time the tail becomes
on screen, the body will already have dimmed.
2. The hold note must be re-used from the pool. We can induce this by
setting the pool sizes to 1 in
[`Column.cs`](https://github.com/ppy/osu/blob/780ce2666099c22d1e0673cafab544418b5d14b0/osu.Game.Rulesets.Mania/UI/Column.cs#L121-L123).
3. The second hold note should be placed far enough in the timeline that
the first hold note dies by the time it becomes visible.
4. Scroll speed should be adjusted to fit the above constraints.
I haven't done a full deep dive into exactly _why_ this is happening, so
the fix here is hand-wavy. That said, just by looking at the old code in
`LegacyBodyPiece` you'll get a feeling that something's bound to go
wrong;
- It never resets the `missingFadeTime` state.
- It never resets the colours back to `Color4.White`.
- It applies transforms onto external components.
- It jumps through hoops to figure out how to set `missingFadeTime`.
My hope is that these changes first bring some sanity in the process,
and if it breaks again I'll consider doing a more proper root cause
(I've had this issue in the back of my mind for about 1 year).
With this PR, they now behave as expected:
https://github.com/user-attachments/assets/140b37c5-cf84-44ba-b797-86ac6d8130c8https://github.com/user-attachments/assets/6f2342a4-6a9a-4941-a55a-24a357f27c25
Per the request of spaceman_atlas, the No Release mod is rewritten to
avoid modifications to DrawableHoldNoteTail. The approach is based
on that of the Strict Tracking mod for the osu!(standard) ruleset,
injecting the mod behavior by replacing the normal hold note with
the mod's variant. The variant inherits most bevaior from the normal
hold note, but when creating nested hitobjects, it creates its own
hold note tail variant instead, which in turn is used to instantiate
the mod's variant of DrawableHoldNoteTail with a new behavior.
The time a judgement is awarded is changed from the end of its
Perfect window to the time of the tail itself.
We've seen multiple cases where DrawableHitObject are stuck in the lifetime management container
due to not implementing a judgement (meaning they are never "hit" or "missed"). To avoid this going forward
CreateJudgement() must be implemented and return a non-null judgement.
This fixes BananaShower and JuiceStreams in osu!catch.
This also makes HitObject abstract and cleans up convert HitObject implementations.