diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs deleted file mode 100644 index 8af63aa5e2..0000000000 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; - -namespace osu.Game.Rulesets.Osu.Tests.Mods -{ - public class TestSceneOsuModFreezeFrame : OsuModTestScene - { - [TestCase(OsuModFreezeFrame.BeatDivisor.Quarter_Measure)] - [TestCase(OsuModFreezeFrame.BeatDivisor.Single_Measure)] - [TestCase(OsuModFreezeFrame.BeatDivisor.Quadruple_Measure)] - public void TestFreezeFrequency(OsuModFreezeFrame.BeatDivisor divisor) - { - CreateModTest(new ModTestData - { - Mod = new OsuModFreezeFrame { Divisor = { Value = divisor } }, - PassCondition = checkSomeHit, - Autoplay = true - }); - } - - [Test] - public void TestWithHidden() - { - var mods = new List { new OsuModHidden(), new OsuModFreezeFrame { Divisor = { Value = OsuModFreezeFrame.BeatDivisor.Quadruple_Measure } } }; - CreateModTest(new ModTestData - { - Mods = mods, - PassCondition = checkSomeHit, - Autoplay = true - }); - } - - private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 8; - } -} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 26adc0f25f..b21e8a4a5f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,22 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; -using System.ComponentModel; -using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : Mod, IApplicableToBeatmap, IApplicableToDrawableRuleset { public override string Name => "Freeze Frame"; @@ -28,80 +23,40 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; - [SettingSource("Beat Divisor", "How often the hitobjects should be grouped according to BPM")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); } - public override void ApplyToBeatmap(IBeatmap beatmap) + public void ApplyToBeatmap(IBeatmap beatmap) { - base.ApplyToBeatmap(beatmap); + double lastNewComboTime = 0; foreach (var obj in beatmap.HitObjects.OfType()) { - // The +1s below are added due to First HitCircle in each measure not appearing appropriately without them. - var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); - double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; - double finalPreempt = obj.TimePreempt + remainder; - applyFadeInAdjustment(obj); + if (obj.NewCombo) { lastNewComboTime = obj.StartTime; } - void applyFadeInAdjustment(OsuHitObject osuObject) + applyFadeInAdjustment(obj); + } + + void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime; + + foreach (var nested in osuObject.NestedHitObjects.OfType()) { - osuObject.TimePreempt = finalPreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyFadeInAdjustment(nested); + switch (nested) + { + //SliderRepeat wont layer correctly if preempt is changed. + case SliderRepeat: + return; + + default: + applyFadeInAdjustment(nested); + break; + } } } } - - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - - private float getMeasure(BeatDivisor divisor) - { - switch (divisor) - { - case BeatDivisor.Quarter_Measure: - return 0.25f; - - case BeatDivisor.Half_Measure: - return 0.5f; - - case BeatDivisor.Single_Measure: - return 1; - - case BeatDivisor.Double_Measure: - return 2; - - case BeatDivisor.Quadruple_Measure: - return 4; - - default: - throw new ArgumentOutOfRangeException(nameof(divisor), divisor, null); - } - } - - public enum BeatDivisor - { - [Description("1/4")] - Quarter_Measure, - - [Description("1/2")] - Half_Measure, - - [Description("1")] - Single_Measure, - - [Description("2")] - Double_Measure, - - [Description("4")] - Quadruple_Measure - } } }