mirror of
https://github.com/ppy/osu.git
synced 2024-12-21 10:32:55 +08:00
103 lines
3.0 KiB
C#
103 lines
3.0 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.
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics.Performance;
|
|
using osu.Game.Rulesets.Objects;
|
|
using osuTK;
|
|
|
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|
{
|
|
public class FollowPointLifetimeEntry : LifetimeEntry
|
|
{
|
|
public event Action? Invalidated;
|
|
public readonly OsuHitObject Start;
|
|
|
|
public FollowPointLifetimeEntry(OsuHitObject start)
|
|
{
|
|
Start = start;
|
|
LifetimeStart = Start.StartTime;
|
|
}
|
|
|
|
private OsuHitObject? end;
|
|
|
|
public OsuHitObject? End
|
|
{
|
|
get => end;
|
|
set
|
|
{
|
|
UnbindEvents();
|
|
|
|
end = value;
|
|
|
|
bindEvents();
|
|
|
|
refreshLifetimes();
|
|
}
|
|
}
|
|
|
|
private bool wasBound;
|
|
|
|
private void bindEvents()
|
|
{
|
|
UnbindEvents();
|
|
|
|
if (End == null)
|
|
return;
|
|
|
|
// Note: Positions are bound for instantaneous feedback from positional changes from the editor, before ApplyDefaults() is called on hitobjects.
|
|
Start.DefaultsApplied += onDefaultsApplied;
|
|
Start.PositionBindable.ValueChanged += onPositionChanged;
|
|
|
|
End.DefaultsApplied += onDefaultsApplied;
|
|
End.PositionBindable.ValueChanged += onPositionChanged;
|
|
|
|
wasBound = true;
|
|
}
|
|
|
|
public void UnbindEvents()
|
|
{
|
|
if (!wasBound)
|
|
return;
|
|
|
|
Debug.Assert(End != null);
|
|
|
|
Start.DefaultsApplied -= onDefaultsApplied;
|
|
Start.PositionBindable.ValueChanged -= onPositionChanged;
|
|
|
|
End.DefaultsApplied -= onDefaultsApplied;
|
|
End.PositionBindable.ValueChanged -= onPositionChanged;
|
|
|
|
wasBound = false;
|
|
}
|
|
|
|
private void onDefaultsApplied(HitObject obj) => refreshLifetimes();
|
|
|
|
private void onPositionChanged(ValueChangedEvent<Vector2> obj) => refreshLifetimes();
|
|
|
|
private void refreshLifetimes()
|
|
{
|
|
if (End == null || End.NewCombo || Start is Spinner || End is Spinner)
|
|
{
|
|
LifetimeEnd = LifetimeStart;
|
|
return;
|
|
}
|
|
|
|
Vector2 startPosition = Start.StackedEndPosition;
|
|
Vector2 endPosition = End.StackedPosition;
|
|
Vector2 distanceVector = endPosition - startPosition;
|
|
|
|
// The lifetime start will match the fade-in time of the first follow point.
|
|
float fraction = (int)(FollowPointConnection.SPACING * 1.5) / distanceVector.Length;
|
|
FollowPointConnection.GetFadeTimes(Start, End, fraction, out double fadeInTime, out _);
|
|
|
|
LifetimeStart = fadeInTime;
|
|
LifetimeEnd = double.MaxValue; // This will be set by the connection.
|
|
|
|
Invalidated?.Invoke();
|
|
}
|
|
}
|
|
}
|