mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 22:22:54 +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.
|
||||
// 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.Containers;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
/// </summary>
|
||||
public abstract class ManiaHitObjectTestScene : ManiaSkinnableTestScene
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
SetContents(() => new FillFlowContainer
|
||||
{
|
||||
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protected abstract DrawableManiaHitObject CreateHitObject();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
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()
|
||||
{
|
||||
var note = new HoldNote { Duration = 1000 };
|
||||
|
@ -51,9 +51,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
public double? HoldStartTime { get; private set; }
|
||||
|
||||
/// <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>
|
||||
public bool HasBroken { get; private set; }
|
||||
public double? HoldBrokenTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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)
|
||||
HasBroken = true;
|
||||
HoldBrokenTime = Time.Current;
|
||||
}
|
||||
|
||||
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 (!Tail.IsHit)
|
||||
HasBroken = true;
|
||||
HoldBrokenTime = Time.Current;
|
||||
|
||||
releaseTime = Time.Current;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
ApplyResult(r =>
|
||||
{
|
||||
// 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;
|
||||
|
||||
r.Type = result;
|
||||
|
@ -18,9 +18,17 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
{
|
||||
public class LegacyBodyPiece : LegacyManiaColumnElement
|
||||
{
|
||||
private DrawableHoldNote holdNote;
|
||||
|
||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||
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]
|
||||
private Drawable bodySprite;
|
||||
|
||||
@ -38,6 +46,8 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject)
|
||||
{
|
||||
holdNote = (DrawableHoldNote)drawableObject;
|
||||
|
||||
string imageName = GetColumnSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value
|
||||
?? $"mania-note{FallbackColumnIndex}L";
|
||||
|
||||
@ -92,11 +102,26 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
InternalChild = bodySprite;
|
||||
|
||||
direction.BindTo(scrollingInfo.Direction);
|
||||
direction.BindValueChanged(onDirectionChanged, true);
|
||||
|
||||
var holdNote = (DrawableHoldNote)drawableObject;
|
||||
isHitting.BindTo(holdNote.IsHitting);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
direction.BindValueChanged(onDirectionChanged, 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)
|
||||
@ -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)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (holdNote != null)
|
||||
holdNote.ApplyCustomUpdateState -= applyCustomUpdateState;
|
||||
|
||||
lightContainer?.Expire();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user