mirror of
https://github.com/ppy/osu.git
synced 2026-05-18 01:30:05 +08:00
d4a4acd3f4
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-86ac6d8130c8 https://github.com/user-attachments/assets/6f2342a4-6a9a-4941-a55a-24a357f27c25
80 lines
2.6 KiB
C#
80 lines
2.6 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.
|
|
|
|
#nullable disable
|
|
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics;
|
|
using osu.Framework.Input.Events;
|
|
using osu.Game.Rulesets.Scoring;
|
|
|
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|
{
|
|
/// <summary>
|
|
/// The tail of a <see cref="DrawableHoldNote"/>.
|
|
/// </summary>
|
|
public partial class DrawableHoldNoteTail : DrawableNote
|
|
{
|
|
/// <summary>
|
|
/// The time at which the user starting missing the hold note.
|
|
/// This could be the time at which they missed the head, broke on the body, or missed the tail.
|
|
/// </summary>
|
|
public readonly IBindable<double?> MissingStartTime = new Bindable<double?>();
|
|
|
|
protected override ManiaSkinComponents Component => ManiaSkinComponents.HoldNoteTail;
|
|
|
|
protected internal DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject;
|
|
|
|
public DrawableHoldNoteTail()
|
|
: this(null)
|
|
{
|
|
}
|
|
|
|
public DrawableHoldNoteTail(TailNote tailNote)
|
|
: base(tailNote)
|
|
{
|
|
Anchor = Anchor.TopCentre;
|
|
Origin = Anchor.TopCentre;
|
|
}
|
|
|
|
protected override void OnApply()
|
|
{
|
|
base.OnApply();
|
|
|
|
if (ParentHitObject is DrawableHoldNote parentHold)
|
|
MissingStartTime.BindTo(parentHold.MissingStartTime);
|
|
}
|
|
|
|
protected override void OnFree()
|
|
{
|
|
base.OnFree();
|
|
|
|
if (ParentHitObject is DrawableHoldNote parentHold)
|
|
MissingStartTime.UnbindFrom(parentHold.MissingStartTime);
|
|
}
|
|
|
|
public void UpdateResult() => base.UpdateResult(true);
|
|
|
|
protected override void CheckForResult(bool userTriggered, double timeOffset) =>
|
|
// Factor in the release lenience
|
|
base.CheckForResult(userTriggered, timeOffset / TailNote.RELEASE_WINDOW_LENIENCE);
|
|
|
|
protected override HitResult GetCappedResult(HitResult result)
|
|
{
|
|
// If the head wasn't hit or the hold note was broken, cap the max score to Meh.
|
|
bool hasComboBreak = !HoldNote.Head.IsHit || HoldNote.Body.HasHoldBreak;
|
|
|
|
if (result > HitResult.Meh && hasComboBreak)
|
|
return HitResult.Meh;
|
|
|
|
return result;
|
|
}
|
|
|
|
public override bool OnPressed(KeyBindingPressEvent<ManiaAction> e) => false; // Handled by the hold note
|
|
|
|
public override void OnReleased(KeyBindingReleaseEvent<ManiaAction> e)
|
|
{
|
|
}
|
|
}
|
|
}
|