diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 2d97f2a237..4a0ed0f9bb 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -2,46 +2,63 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Audio; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; +using osuTK; namespace osu.Game.Rulesets.Mods { public abstract class ModTimeRamp : Mod { public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime), typeof(ModHalfTime) }; - public abstract double AppendRate { get; } + + protected abstract double FinalRateAdjustment { get; } } public abstract class ModTimeRamp : ModTimeRamp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap where T : HitObject { - private double lastObjectEndTime; + private double finalRateTime; + + private double beginRampTime; + private IAdjustableClock clock; + private IHasPitchAdjust pitchAdjust; - public virtual void ApplyToClock(IAdjustableClock clk) + /// + /// The point in the beatmap at which the final ramping rate should be reached. + /// + private const double final_rate_progress = 0.75f; + + public virtual void ApplyToClock(IAdjustableClock clock) { - clock = clk; - pitchAdjust = clk as IHasPitchAdjust; - pitchAdjust.PitchAdjust = 1.0 + AppendRate; + this.clock = clock; + pitchAdjust = (IHasPitchAdjust)clock; + + // for preview purposes + pitchAdjust.PitchAdjust = 1.0 + FinalRateAdjustment; } public virtual void ApplyToBeatmap(Beatmap beatmap) { - HitObject lastObject = beatmap.HitObjects[beatmap.HitObjects.Count - 1]; - lastObjectEndTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + HitObject lastObject = beatmap.HitObjects.LastOrDefault(); + + beginRampTime = beatmap.HitObjects.FirstOrDefault()?.StartTime ?? 0; + finalRateTime = final_rate_progress * ((lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0); } public virtual void Update(Playfield playfield) { - double newRate = 1 + AppendRate < 1 ? Math.Max(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))) : - Math.Min(1 + AppendRate, 1 + (AppendRate * (clock.CurrentTime / (lastObjectEndTime * 0.75)))); - pitchAdjust.PitchAdjust = newRate; + var absRate = Math.Abs(FinalRateAdjustment); + var adjustment = MathHelper.Clamp(absRate * ((clock.CurrentTime - beginRampTime) / finalRateTime), 0, absRate); + + pitchAdjust.PitchAdjust = 1 + Math.Sign(FinalRateAdjustment) * adjustment; } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 4054cd10a5..646c5c64e4 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mods public override string Description => "Sloooow doooown..."; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_down; public override double ScoreMultiplier => 1.0; - public override double AppendRate => -0.25; + protected override double FinalRateAdjustment => -0.25; } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index cdae60fcf1..9050b5591a 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mods public override string Description => "Can you keep up?"; public override FontAwesome Icon => FontAwesome.fa_chevron_circle_up; public override double ScoreMultiplier => 1.0; - public override double AppendRate => 0.5; + protected override double FinalRateAdjustment => 0.5; } } \ No newline at end of file