mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 01:52:55 +08:00
Merge pull request #10831 from bdach/hold-note-fade
Add back fade effect to legacy hold notes
This commit is contained in:
commit
bcf6974e18
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ManiaHitObjectTestScene : ManiaSkinnableTestScene
|
public abstract class ManiaHitObjectTestScene : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
[BackgroundDependencyLoader]
|
[SetUp]
|
||||||
private void load()
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
SetContents(() => new FillFlowContainer
|
SetContents(() => new FillFlowContainer
|
||||||
{
|
{
|
||||||
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
protected abstract DrawableManiaHitObject CreateHitObject();
|
protected abstract DrawableManiaHitObject CreateHitObject();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -26,6 +27,18 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFadeOnMiss()
|
||||||
|
{
|
||||||
|
AddStep("miss tick", () =>
|
||||||
|
{
|
||||||
|
foreach (var holdNote in holdNotes)
|
||||||
|
holdNote.ChildrenOfType<DrawableHoldNoteHead>().First().MissForcefully();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DrawableHoldNote> holdNotes => CreatedDrawables.SelectMany(d => d.ChildrenOfType<DrawableHoldNote>());
|
||||||
|
|
||||||
protected override DrawableManiaHitObject CreateHitObject()
|
protected override DrawableManiaHitObject CreateHitObject()
|
||||||
{
|
{
|
||||||
var note = new HoldNote { Duration = 1000 };
|
var note = new HoldNote { Duration = 1000 };
|
||||||
|
@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
public double? HoldStartTime { get; private set; }
|
public double? HoldStartTime { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the hold note has been released too early and shouldn't give full score for the release.
|
/// Time at which the hold note has been broken, i.e. released too early, resulting in a reduced score.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasBroken { get; private set; }
|
public double? HoldBrokenTime { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the hold note has been released potentially without having caused a break.
|
/// Whether the hold note has been released potentially without having caused a break.
|
||||||
@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Tail.Judged && !Tail.IsHit)
|
if (Tail.Judged && !Tail.IsHit)
|
||||||
HasBroken = true;
|
HoldBrokenTime = Time.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
@ -298,7 +298,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
// If the key has been released too early, the user should not receive full score for the release
|
// If the key has been released too early, the user should not receive full score for the release
|
||||||
if (!Tail.IsHit)
|
if (!Tail.IsHit)
|
||||||
HasBroken = true;
|
HoldBrokenTime = Time.Current;
|
||||||
|
|
||||||
releaseTime = Time.Current;
|
releaseTime = Time.Current;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
ApplyResult(r =>
|
ApplyResult(r =>
|
||||||
{
|
{
|
||||||
// If the head wasn't hit or the hold note was broken, cap the max score to Meh.
|
// If the head wasn't hit or the hold note was broken, cap the max score to Meh.
|
||||||
if (result > HitResult.Meh && (!holdNote.Head.IsHit || holdNote.HasBroken))
|
if (result > HitResult.Meh && (!holdNote.Head.IsHit || holdNote.HoldBrokenTime != null))
|
||||||
result = HitResult.Meh;
|
result = HitResult.Meh;
|
||||||
|
|
||||||
r.Type = result;
|
r.Type = result;
|
||||||
|
@ -18,9 +18,17 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
{
|
{
|
||||||
public class LegacyBodyPiece : LegacyManiaColumnElement
|
public class LegacyBodyPiece : LegacyManiaColumnElement
|
||||||
{
|
{
|
||||||
|
private DrawableHoldNote holdNote;
|
||||||
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
private readonly IBindable<bool> isHitting = new Bindable<bool>();
|
private readonly IBindable<bool> isHitting = new Bindable<bool>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the start time of the fade animation that plays when any of the nested
|
||||||
|
/// hitobjects of the hold note are missed.
|
||||||
|
/// </summary>
|
||||||
|
private readonly Bindable<double?> missFadeTime = new Bindable<double?>();
|
||||||
|
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private Drawable bodySprite;
|
private Drawable bodySprite;
|
||||||
|
|
||||||
@ -38,6 +46,8 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject)
|
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject)
|
||||||
{
|
{
|
||||||
|
holdNote = (DrawableHoldNote)drawableObject;
|
||||||
|
|
||||||
string imageName = GetColumnSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value
|
string imageName = GetColumnSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value
|
||||||
?? $"mania-note{FallbackColumnIndex}L";
|
?? $"mania-note{FallbackColumnIndex}L";
|
||||||
|
|
||||||
@ -92,11 +102,26 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
InternalChild = bodySprite;
|
InternalChild = bodySprite;
|
||||||
|
|
||||||
direction.BindTo(scrollingInfo.Direction);
|
direction.BindTo(scrollingInfo.Direction);
|
||||||
direction.BindValueChanged(onDirectionChanged, true);
|
|
||||||
|
|
||||||
var holdNote = (DrawableHoldNote)drawableObject;
|
|
||||||
isHitting.BindTo(holdNote.IsHitting);
|
isHitting.BindTo(holdNote.IsHitting);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
direction.BindValueChanged(onDirectionChanged, true);
|
||||||
isHitting.BindValueChanged(onIsHittingChanged, true);
|
isHitting.BindValueChanged(onIsHittingChanged, true);
|
||||||
|
missFadeTime.BindValueChanged(onMissFadeTimeChanged, true);
|
||||||
|
|
||||||
|
holdNote.ApplyCustomUpdateState += applyCustomUpdateState;
|
||||||
|
applyCustomUpdateState(holdNote, holdNote.State.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyCustomUpdateState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
// ensure that the hold note is also faded out when the head/tail/any tick is missed.
|
||||||
|
if (state == ArmedState.Miss)
|
||||||
|
missFadeTime.Value ??= hitObject.HitStateUpdateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onIsHittingChanged(ValueChangedEvent<bool> isHitting)
|
private void onIsHittingChanged(ValueChangedEvent<bool> isHitting)
|
||||||
@ -158,10 +183,38 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onMissFadeTimeChanged(ValueChangedEvent<double?> missFadeTimeChange)
|
||||||
|
{
|
||||||
|
if (missFadeTimeChange.NewValue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// this update could come from any nested object of the hold note (or even from an input).
|
||||||
|
// make sure the transforms are consistent across all affected parts.
|
||||||
|
using (BeginAbsoluteSequence(missFadeTimeChange.NewValue.Value))
|
||||||
|
{
|
||||||
|
// colour and duration matches stable
|
||||||
|
// transforms not applied to entire hold note in order to not affect hit lighting
|
||||||
|
const double fade_duration = 60;
|
||||||
|
|
||||||
|
holdNote.Head.FadeColour(Colour4.DarkGray, fade_duration);
|
||||||
|
holdNote.Tail.FadeColour(Colour4.DarkGray, fade_duration);
|
||||||
|
bodySprite?.FadeColour(Colour4.DarkGray, fade_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
missFadeTime.Value ??= holdNote.HoldBrokenTime;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (holdNote != null)
|
||||||
|
holdNote.ApplyCustomUpdateState -= applyCustomUpdateState;
|
||||||
|
|
||||||
lightContainer?.Expire();
|
lightContainer?.Expire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user