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; + } } }