diff --git a/osu.Game.Mode.Osu/Objects/Slider.cs b/osu.Game.Mode.Osu/Objects/Slider.cs index 3e0d899745..114b87eaaf 100644 --- a/osu.Game.Mode.Osu/Objects/Slider.cs +++ b/osu.Game.Mode.Osu/Objects/Slider.cs @@ -2,18 +2,20 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Game.Database; using OpenTK; namespace osu.Game.Modes.Osu.Objects { public class Slider : OsuHitObject { - public override double EndTime => StartTime + (RepeatCount + 1) * Curve.Length; + public override double EndTime => StartTime + (RepeatCount + 1) * Curve.Length / VelocityAt(StartTime); + + public double VelocityAt(double time) => 10000 / Beatmap.BeatLengthAt(time, true) * Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier; public int RepeatCount; public SliderCurve Curve; - } public class SliderCurve diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 4d6c6a8056..3f8ae0e33a 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -16,5 +16,27 @@ namespace osu.Game.Beatmaps public List HitObjects { get; set; } public List ControlPoints { get; set; } public List ComboColors { get; set; } + + public double BeatLengthAt(double time, bool applyMultipliers = false) + { + int point = 0; + int samplePoint = 0; + + for (int i = 0; i < ControlPoints.Count; i++) + if (ControlPoints[i].Time <= time) + { + if (ControlPoints[i].TimingChange) + point = i; + else + samplePoint = i; + } + + double mult = 1; + + if (applyMultipliers && samplePoint > point && ControlPoints[samplePoint].BeatLength < 0) + mult = ControlPoints[samplePoint].VelocityAdjustment; + + return ControlPoints[point].BeatLength * mult; + } } } diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index ebb718af1b..7297a78c63 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -294,8 +294,12 @@ namespace osu.Game.Beatmaps.Formats break; case Section.HitObjects: var obj = parser?.Parse(val); + if (obj != null) + { + obj.Beatmap = beatmap; beatmap.HitObjects.Add(obj); + } break; } } diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index abb88726b6..ff352f9321 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -1,6 +1,7 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Samples; using OpenTK.Graphics; @@ -20,6 +21,8 @@ namespace osu.Game.Modes.Objects public double Duration => EndTime - StartTime; + public Beatmap Beatmap; + public HitSampleInfo Sample; } }