diff --git a/osu.Game.Rulesets.Mania/Mods/IManiaRateAdjustmentMod.cs b/osu.Game.Rulesets.Mania/Mods/IManiaRateAdjustmentMod.cs new file mode 100644 index 0000000000..ea01bd4436 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/IManiaRateAdjustmentMod.cs @@ -0,0 +1,47 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Scoring; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Mania.Mods +{ + /// + /// May be attached to rate-adjustment mods to adjust hit windows adjust relative to gameplay rate. + /// + /// + /// Historically, in osu!mania, hit windows are expected to adjust relative to the gameplay rate such that the real-world hit window remains the same. + /// + public interface IManiaRateAdjustmentMod : IApplicableToDifficulty, IApplicableToHitObject + { + BindableNumber SpeedChange { get; } + + HitWindows HitWindows { get; set; } + + void IApplicableToDifficulty.ApplyToDifficulty(BeatmapDifficulty difficulty) + { + HitWindows = new ManiaHitWindows(SpeedChange.Value); + HitWindows.SetDifficulty(difficulty.OverallDifficulty); + } + + void IApplicableToHitObject.ApplyToHitObject(HitObject hitObject) + { + switch (hitObject) + { + case Note: + hitObject.HitWindows = HitWindows; + break; + + case HoldNote hold: + hold.Head.HitWindows = HitWindows; + hold.Tail.HitWindows = HitWindows; + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs index 309393b664..dbe2a9a9fc 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModDaycore : ModDaycore + public class ManiaModDaycore : ModDaycore, IManiaRateAdjustmentMod { + public HitWindows HitWindows { get; set; } = new ManiaHitWindows(); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs index f4b9cf3b88..a841a8ab37 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModDoubleTime : ModDoubleTime + public class ManiaModDoubleTime : ModDoubleTime, IManiaRateAdjustmentMod { + public HitWindows HitWindows { get; set; } = new ManiaHitWindows(); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs index 8d48e3acde..b0fbb11396 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModHalfTime : ModHalfTime + public class ManiaModHalfTime : ModHalfTime, IManiaRateAdjustmentMod { + public HitWindows HitWindows { get; set; } = new ManiaHitWindows(); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs index 748725af9f..f64f7ae31a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs @@ -2,11 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModNightcore : ModNightcore + public class ManiaModNightcore : ModNightcore, IManiaRateAdjustmentMod { + public HitWindows HitWindows { get; set; } = new ManiaHitWindows(); } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaHitWindows.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaHitWindows.cs index 289f8a00ef..627f48f391 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaHitWindows.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaHitWindows.cs @@ -1,12 +1,25 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Scoring { public class ManiaHitWindows : HitWindows { + private readonly double multiplier; + + public ManiaHitWindows() + : this(1) + { + } + + public ManiaHitWindows(double multiplier) + { + this.multiplier = multiplier; + } + public override bool IsHitResultAllowed(HitResult result) { switch (result) @@ -22,5 +35,12 @@ namespace osu.Game.Rulesets.Mania.Scoring return false; } + + protected override DifficultyRange[] GetRanges() => base.GetRanges().Select(r => + new DifficultyRange( + r.Result, + r.Min * multiplier, + r.Average * multiplier, + r.Max * multiplier)).ToArray(); } }