diff --git a/osu-framework b/osu-framework
index aa3e296968..0f3db5da09 160000
--- a/osu-framework
+++ b/osu-framework
@@ -1 +1 @@
-Subproject commit aa3e296968873208ca4460b00c0b82fe3aa8ff5c
+Subproject commit 0f3db5da09d0e7c4d2ef3057030e018f34ba536e
diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
index cb1d9d2fcd..c6aac3bb71 100644
--- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
@@ -428,6 +428,9 @@ namespace osu.Game.Beatmaps.Formats
break;
}
}
+
+ foreach (var hitObject in beatmap.HitObjects)
+ hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.Difficulty);
}
internal enum LegacySampleBank
diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
index 237aaa44a6..ebaef661c4 100644
--- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
+++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
@@ -5,18 +5,21 @@ using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Framework.Extensions.Color4Extensions;
+using osu.Game.Graphics.Containers;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Framework.Audio.Track;
+using System;
namespace osu.Game.Graphics.UserInterface
{
public class TwoLayerButton : ClickableContainer
{
- private readonly TextAwesome icon;
+ private readonly BouncingIcon bouncingIcon;
public Box IconLayer;
public Box TextLayer;
@@ -95,11 +98,10 @@ namespace osu.Game.Graphics.UserInterface
},
}
},
- icon = new TextAwesome
+ bouncingIcon = new BouncingIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- TextSize = 25,
},
}
},
@@ -146,7 +148,7 @@ namespace osu.Game.Graphics.UserInterface
{
set
{
- icon.Icon = value;
+ bouncingIcon.Icon = value;
}
}
@@ -162,58 +164,20 @@ namespace osu.Game.Graphics.UserInterface
protected override bool OnHover(InputState state)
{
- icon.ClearTransforms();
-
ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic);
-
- int duration = 0; //(int)(Game.Audio.BeatLength / 2);
- if (duration == 0) duration = pulse_length;
-
IconLayer.FadeColour(HoverColour, transform_time, EasingTypes.OutElastic);
- const double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
- double startTime = Time.Current + offset;
-
- // basic pulse
- icon.Transforms.Add(new TransformScale
- {
- StartValue = new Vector2(1.1f),
- EndValue = Vector2.One,
- StartTime = startTime,
- EndTime = startTime + duration,
- Easing = EasingTypes.Out,
- LoopCount = -1,
- LoopDelay = duration
- });
+ bouncingIcon.ScaleTo(1.1f, transform_time, EasingTypes.OutElastic);
return true;
}
protected override void OnHoverLost(InputState state)
{
- icon.ClearTransforms();
-
ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic);
-
IconLayer.FadeColour(TextLayer.Colour, transform_time, EasingTypes.OutElastic);
- int duration = 0; //(int)(Game.Audio.BeatLength);
- if (duration == 0) duration = pulse_length * 2;
-
- const double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration;
- double startTime = Time.Current + offset;
-
- // slow pulse
- icon.Transforms.Add(new TransformScale
- {
- StartValue = new Vector2(1.1f),
- EndValue = Vector2.One,
- StartTime = startTime,
- EndTime = startTime + duration,
- Easing = EasingTypes.Out,
- LoopCount = -1,
- LoopDelay = duration
- });
+ bouncingIcon.ScaleTo(1, transform_time, EasingTypes.OutElastic);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
@@ -239,5 +203,45 @@ namespace osu.Game.Graphics.UserInterface
return base.OnClick(state);
}
+
+ private class BouncingIcon : BeatSyncedContainer
+ {
+ private const double beat_in_time = 60;
+
+ private readonly TextAwesome icon;
+
+ public FontAwesome Icon { set { icon.Icon = value; } }
+
+ public BouncingIcon()
+ {
+ EarlyActivationMilliseconds = beat_in_time;
+ AutoSizeAxes = Axes.Both;
+
+ Children = new Drawable[]
+ {
+ icon = new TextAwesome
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ TextSize = 25
+ }
+ };
+ }
+
+ protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
+ {
+ base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
+
+ var beatLength = timingPoint.BeatLength;
+
+ float amplitudeAdjust = Math.Min(1, 0.4f + amplitudes.Maximum);
+
+ if (beatIndex < 0) return;
+
+ icon.ScaleTo(1 - 0.1f * amplitudeAdjust, beat_in_time, EasingTypes.Out);
+ using (icon.BeginDelayedSequence(beat_in_time))
+ icon.ScaleTo(1, beatLength * 2, EasingTypes.OutQuint);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs
index 7580404e81..8c2aead5ff 100644
--- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs
+++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs
@@ -6,20 +6,30 @@ using System;
using System.Collections.Generic;
using OpenTK;
using osu.Game.Audio;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Database;
namespace osu.Game.Rulesets.Objects.Legacy
{
internal abstract class ConvertSlider : HitObject, IHasCurve
{
+ ///
+ /// Scoring distance with a speed-adjusted beat length of 1 second.
+ ///
+ private const float base_scoring_distance = 100;
+
public List ControlPoints { get; set; }
public CurveType CurveType { get; set; }
+
public double Distance { get; set; }
public List RepeatSamples { get; set; }
public int RepeatCount { get; set; } = 1;
- public double EndTime { get; set; }
- public double Duration { get; set; }
+ public double EndTime => StartTime + RepeatCount * Distance / Velocity;
+ public double Duration => EndTime - StartTime;
+
+ public double Velocity = 1;
public Vector2 PositionAt(double progress)
{
@@ -35,5 +45,17 @@ namespace osu.Game.Rulesets.Objects.Legacy
{
throw new NotImplementedException();
}
+
+ public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
+ {
+ base.ApplyDefaults(controlPointInfo, difficulty);
+
+ TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
+ DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
+
+ double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier / difficultyPoint.SpeedMultiplier;
+
+ Velocity = scoringDistance / timingPoint.BeatLength;
+ }
}
}