From 7add3a69508abd2d2cffc9f9ec0ebe329b9faa26 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 18 Aug 2022 19:00:54 +0200 Subject: [PATCH 01/23] ar var test --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs new file mode 100644 index 0000000000..e291e92901 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -0,0 +1,61 @@ +// 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.Framework.Bindables; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModFlash : ModWithVisibilityAdjustment, IApplicableAfterBeatmapConversion + { + public override string Name => "Var AR Test"; + public override string Acronym => "TP"; + public override ModType Type => ModType.Fun; + public override IconUsage? Icon => FontAwesome.Regular.Sun; + public override string Description => @"how far will your reading stretch"; + public override double ScoreMultiplier => 1.03; + + public override void ApplyToBeatmap(IBeatmap beatmap) + { + base.ApplyToBeatmap(beatmap); + double lastObjectEnd = beatmap.HitObjects.LastOrDefault()?.GetEndTime() ?? 0; + + foreach (var obj in beatmap.HitObjects.OfType()) + applyVariableAr(obj); + + void applyVariableAr(OsuHitObject osuObject) + { + double percentageofmap = osuObject.StartTime / lastObjectEnd; + osuObject.TimePreempt = (percentageofmap * osuObject.TimePreempt) * ARadded.Value + osuObject.TimePreempt; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyVariableAr(nested); + } + } + + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) + { + } + + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) + { + } + + [SettingSource("Additional AR", "how much AR change to add")] + public BindableDouble ARadded { get; } = new BindableDouble(1) + { + Precision = 0.1f, + MinValue = 0, + MaxValue = 10, + }; + + /*[SettingSource("Additional Ar", "how much ar change to add")] + public BindableBool scaledown { get; } = new BindableBool();*/ + } +} From 5a1b2f9a77b62f0ef01e010bfef942ff68385b9f Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 00:05:48 +0200 Subject: [PATCH 02/23] Freeze frame testing --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 85 ++++++++++++++--------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index e291e92901..b50de12465 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -1,61 +1,84 @@ -// 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 osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.UI; +using osuTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlash : ModWithVisibilityAdjustment, IApplicableAfterBeatmapConversion + public class OsuModFlash : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Var AR Test"; - public override string Acronym => "TP"; + public override string Name => "Freeze frame"; + + public override string Acronym => "FF"; + + public override double ScoreMultiplier => 1; + + public override string Description => "Burn the notes into your memory"; + public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Regular.Sun; - public override string Description => @"how far will your reading stretch"; - public override double ScoreMultiplier => 1.03; + + public override IconUsage? Icon => FontAwesome.Solid.Fire; + + public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; + + [SettingSource("Beat divisor")] + public BindableFloat BeatDivisor { get; } = new BindableFloat(2) + { + MinValue = .25f, + MaxValue = 2, + Precision = .25F + }; public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); - double lastObjectEnd = beatmap.HitObjects.LastOrDefault()?.GetEndTime() ?? 0; - foreach (var obj in beatmap.HitObjects.OfType()) - applyVariableAr(obj); - - void applyVariableAr(OsuHitObject osuObject) + foreach (var hitObject in beatmap.HitObjects.OfType()) { - double percentageofmap = osuObject.StartTime / lastObjectEnd; - osuObject.TimePreempt = (percentageofmap * osuObject.TimePreempt) * ARadded.Value + osuObject.TimePreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyVariableAr(nested); + hitObject.TimeFadeIn = hitObject.TimePreempt; + var point = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); + hitObject.TimePreempt += hitObject.StartTime % (point.BeatLength / BeatDivisor.Value); } } + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); + } + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); + + private void applyFrozenState(DrawableHitObject drawable, ArmedState state) { + if (drawable is DrawableSpinner) + return; + + var h = (OsuHitObject)drawable.HitObject; + + switch (drawable) + { + case DrawableHitCircle circle: + using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt)) + { + circle.ApproachCircle.Hide(); + } + + break; + } } - - [SettingSource("Additional AR", "how much AR change to add")] - public BindableDouble ARadded { get; } = new BindableDouble(1) - { - Precision = 0.1f, - MinValue = 0, - MaxValue = 10, - }; - - /*[SettingSource("Additional Ar", "how much ar change to add")] - public BindableBool scaledown { get; } = new BindableBool();*/ } } + diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 302194e91a..466b770399 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -198,7 +198,8 @@ namespace osu.Game.Rulesets.Osu new OsuModMuted(), new OsuModNoScope(), new MultiMod(new OsuModMagnetised(), new OsuModRepel()), - new ModAdaptiveSpeed() + new ModAdaptiveSpeed(), + new OsuModFlash() }; case ModType.System: From 7f08de522d68efd5d79e7b08d1d64e1ed81454f3 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 01:21:03 +0200 Subject: [PATCH 03/23] Fixed --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index b50de12465..e1ce43d875 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; @@ -10,7 +11,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; -using osuTK; namespace osu.Game.Rulesets.Osu.Mods { @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1; - public override string Description => "Burn the notes into your memory"; + public override LocalisableString Description => "Burn the notes into your memory"; public override ModType Type => ModType.Fun; @@ -31,22 +31,29 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] - public BindableFloat BeatDivisor { get; } = new BindableFloat(2) + public BindableFloat BeatDivisor { get; } = new BindableFloat(1) { MinValue = .25f, - MaxValue = 2, - Precision = .25F + MaxValue = 5, + Precision = .25f }; public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); - foreach (var hitObject in beatmap.HitObjects.OfType()) + foreach (var obj in beatmap.HitObjects.OfType()) { - hitObject.TimeFadeIn = hitObject.TimePreempt; - var point = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); - hitObject.TimePreempt += hitObject.StartTime % (point.BeatLength / BeatDivisor.Value); + applyFadeInAdjustment(obj); + var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); + obj.TimePreempt += obj.StartTime % (point.BeatLength * BeatDivisor.Value); + } + + static void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimeFadeIn = osuObject.TimePreempt; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyFadeInAdjustment(nested); } } From 4a6c8785af7bd24b5f2e4a1be9e85c19624ac4c8 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 11:14:56 +0200 Subject: [PATCH 04/23] Clean up --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index e1ce43d875..818eb93bfb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -38,30 +38,31 @@ namespace osu.Game.Rulesets.Osu.Mods Precision = .25f }; + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); + } + public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); foreach (var obj in beatmap.HitObjects.OfType()) { - applyFadeInAdjustment(obj); var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - obj.TimePreempt += obj.StartTime % (point.BeatLength * BeatDivisor.Value); - } + double val = obj.TimePreempt + obj.StartTime % (point.BeatLength * BeatDivisor.Value); + applyFadeInAdjustment(obj); - static void applyFadeInAdjustment(OsuHitObject osuObject) - { - osuObject.TimeFadeIn = osuObject.TimePreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyFadeInAdjustment(nested); + void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimePreempt = val; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyFadeInAdjustment(nested); + } } } - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); - } - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } @@ -74,7 +75,7 @@ namespace osu.Game.Rulesets.Osu.Mods return; var h = (OsuHitObject)drawable.HitObject; - + /* switch (drawable) { case DrawableHitCircle circle: @@ -84,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Mods } break; - } + }*/ } } } From e416c87970de92b0b10e27733c2509bfacdf215c Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 15:17:22 +0200 Subject: [PATCH 05/23] readded approach circles --- .../{OsuModFlash.cs => OsuModFreezeFrame.cs} | 23 +++---------------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 2 files changed, 4 insertions(+), 21 deletions(-) rename osu.Game.Rulesets.Osu/Mods/{OsuModFlash.cs => OsuModFreezeFrame.cs} (76%) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs similarity index 76% rename from osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs rename to osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 818eb93bfb..b6b6f4e588 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -8,13 +8,12 @@ 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.Objects.Drawables; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlash : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { public override string Name => "Freeze frame"; @@ -26,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Solid.Fire; + public override IconUsage? Icon => FontAwesome.Solid.Camera; public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; @@ -38,7 +37,6 @@ namespace osu.Game.Rulesets.Osu.Mods Precision = .25f }; - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); @@ -69,23 +67,8 @@ namespace osu.Game.Rulesets.Osu.Mods protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); - private void applyFrozenState(DrawableHitObject drawable, ArmedState state) + private void applyFrozenState(DrawableHitObject drawableObject, ArmedState state) { - if (drawable is DrawableSpinner) - return; - - var h = (OsuHitObject)drawable.HitObject; - /* - switch (drawable) - { - case DrawableHitCircle circle: - using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt)) - { - circle.ApproachCircle.Hide(); - } - - break; - }*/ } } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 6fdf4c3bf8..2b42dc7eef 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -202,7 +202,7 @@ namespace osu.Game.Rulesets.Osu new OsuModNoScope(), new MultiMod(new OsuModMagnetised(), new OsuModRepel()), new ModAdaptiveSpeed(), - new OsuModFlash() + new OsuModFreezeFrame() }; case ModType.System: From cb17fb2091b351c0bf79f31a0818923529d2b274 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 9 Sep 2022 23:13:19 +0200 Subject: [PATCH 06/23] Create Test Scene --- .../Mods/TestSceneOsuModFreezeFrame.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs new file mode 100644 index 0000000000..4642229436 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -0,0 +1,27 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModFreezeFrame : OsuModTestScene + { + [TestCase(0.5f)] + [TestCase(1)] + [TestCase(2)] + public void TestFreezeFrequency(float beatMeasure) + { + CreateModTest(new ModTestData + { + Mod = new OsuModFreezeFrame + { + BeatDivisor = { Value = beatMeasure } + }, + PassCondition = () => true, + Autoplay = true + }); + } + } +} From 23d435bc427c8d1e2780a46d500b77eff084c9df Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Sat, 10 Sep 2022 14:08:04 +0200 Subject: [PATCH 07/23] name changes --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index b6b6f4e588..6bbe01063b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -49,12 +49,12 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - double val = obj.TimePreempt + obj.StartTime % (point.BeatLength * BeatDivisor.Value); + double newPreempt = obj.TimePreempt + (obj.StartTime +5) % (point.BeatLength * BeatDivisor.Value); applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) { - osuObject.TimePreempt = val; + osuObject.TimePreempt = newPreempt; foreach (var nested in osuObject.NestedHitObjects.OfType()) applyFadeInAdjustment(nested); } From eb84c513e34a682914322ee94bf78b6836e64e1a Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 02:14:14 +0200 Subject: [PATCH 08/23] Add ability to adjust to BPM changes fix first hitcircle being off time Bpm changes not working fix --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6bbe01063b..84e41810ab 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] @@ -48,13 +47,17 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { - var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - double newPreempt = obj.TimePreempt + (obj.StartTime +5) % (point.BeatLength * BeatDivisor.Value); + var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); + double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * BeatDivisor.Value); + + double finalPreempt = obj.TimePreempt + remainder; + obj.TimePreempt = finalPreempt; applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) { - osuObject.TimePreempt = newPreempt; + osuObject.TimePreempt = finalPreempt; foreach (var nested in osuObject.NestedHitObjects.OfType()) applyFadeInAdjustment(nested); } From 5a9b027ebcb32ecb44f6985ea86813682b5202f9 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 02:57:21 +0200 Subject: [PATCH 09/23] Use Enum for Settings --- .../Mods/OsuModFreezeFrame.cs | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 84e41810ab..42c4a8fa20 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -29,12 +29,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] - public BindableFloat BeatDivisor { get; } = new BindableFloat(1) - { - MinValue = .25f, - MaxValue = 5, - Precision = .25f - }; + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -48,11 +43,11 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); + // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * BeatDivisor.Value); + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); double finalPreempt = obj.TimePreempt + remainder; - obj.TimePreempt = finalPreempt; applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) @@ -64,14 +59,41 @@ namespace osu.Game.Rulesets.Osu.Mods } } - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) + 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.Measure: + return 1; + + case BeatDivisor.Double_Measure: + return 2; + + case BeatDivisor.Quadruple_Measure: + return 4; + + default: + throw new ArgumentOutOfRangeException(nameof(divisor), divisor, null); + } } - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); - - private void applyFrozenState(DrawableHitObject drawableObject, ArmedState state) + public enum BeatDivisor { + Quarter_Measure, + Half_Measure, + Measure, + Double_Measure, + Quadruple_Measure } } } From 7fc0366afd56bfea4fcc91c45fc14124924218a6 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:18:38 +0200 Subject: [PATCH 10/23] Improve Tests Fix divisor in test --- .../Mods/TestSceneOsuModFreezeFrame.cs | 31 +++++++++++++------ .../Mods/OsuModFreezeFrame.cs | 17 +++++----- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs index 4642229436..8af63aa5e2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -1,27 +1,40 @@ // 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(0.5f)] - [TestCase(1)] - [TestCase(2)] - public void TestFreezeFrequency(float beatMeasure) + [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 - { - BeatDivisor = { Value = beatMeasure } - }, - PassCondition = () => true, + 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 42c4a8fa20..08a8a85740 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Freeze frame"; + public override string Name => "Freeze Frame"; public override string Acronym => "FF"; @@ -26,10 +26,9 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; - [SettingSource("Beat divisor")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); + [SettingSource("Measure", "How often the hitcircles should be Grouped to freeze")] + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -42,11 +41,10 @@ namespace osu.Game.Rulesets.Osu.Mods 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); - // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); - + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; double finalPreempt = obj.TimePreempt + remainder; applyFadeInAdjustment(obj); @@ -73,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Mods case BeatDivisor.Half_Measure: return 0.5f; - case BeatDivisor.Measure: + case BeatDivisor.Single_Measure: return 1; case BeatDivisor.Double_Measure: @@ -87,11 +85,12 @@ namespace osu.Game.Rulesets.Osu.Mods } } + //Todo: find better way to represent these Enums to the player public enum BeatDivisor { Quarter_Measure, Half_Measure, - Measure, + Single_Measure, Double_Measure, Quadruple_Measure } From 427bd182697cf40af987cd09526f643213752520 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:36:04 +0200 Subject: [PATCH 11/23] Add Copyright header --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 08a8a85740..6b29c511ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,3 +1,6 @@ +// 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 osu.Framework.Bindables; @@ -27,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override IconUsage? Icon => FontAwesome.Solid.Camera; - [SettingSource("Measure", "How often the hitcircles should be Grouped to freeze")] + [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) From 6db8f51c02fd7d96e67870951a02ded4eb7c865b Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:45:18 +0200 Subject: [PATCH 12/23] Improve Tests Fix divisor in test Add Copyright header --- .../Mods/TestSceneOsuModFreezeFrame.cs | 31 +++++++++++++------ .../Mods/OsuModFreezeFrame.cs | 20 ++++++------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs index 4642229436..8af63aa5e2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -1,27 +1,40 @@ // 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(0.5f)] - [TestCase(1)] - [TestCase(2)] - public void TestFreezeFrequency(float beatMeasure) + [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 - { - BeatDivisor = { Value = beatMeasure } - }, - PassCondition = () => true, + 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 42c4a8fa20..6b29c511ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,3 +1,6 @@ +// 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 osu.Framework.Bindables; @@ -15,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Freeze frame"; + public override string Name => "Freeze Frame"; public override string Acronym => "FF"; @@ -26,10 +29,9 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; - [SettingSource("Beat divisor")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); + [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -42,11 +44,10 @@ namespace osu.Game.Rulesets.Osu.Mods 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); - // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); - + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; double finalPreempt = obj.TimePreempt + remainder; applyFadeInAdjustment(obj); @@ -73,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Mods case BeatDivisor.Half_Measure: return 0.5f; - case BeatDivisor.Measure: + case BeatDivisor.Single_Measure: return 1; case BeatDivisor.Double_Measure: @@ -87,11 +88,12 @@ namespace osu.Game.Rulesets.Osu.Mods } } + //Todo: find better way to represent these Enums to the player public enum BeatDivisor { Quarter_Measure, Half_Measure, - Measure, + Single_Measure, Double_Measure, Quadruple_Measure } From a0c493656f7e738bb0fe5d52d00308ebc4310ab2 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 15:27:36 +0200 Subject: [PATCH 13/23] Remove Incompatibility with Approach Circle requiring mods --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6b29c511ec..6a0faf9298 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset { public override string Name => "Freeze Frame"; From 6d3e42a248021605150fbda3a7cfb8d9a4b98dd4 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Sun, 18 Sep 2022 19:35:12 +0200 Subject: [PATCH 14/23] Give enums descriptions, change acronym and remove icon --- .../Mods/OsuModFreezeFrame.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6a0faf9298..26adc0f25f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -3,8 +3,8 @@ using System; using System.Linq; +using System.ComponentModel; using osu.Framework.Bindables; -using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -20,17 +20,15 @@ namespace osu.Game.Rulesets.Osu.Mods { public override string Name => "Freeze Frame"; - public override string Acronym => "FF"; + public override string Acronym => "FR"; public override double ScoreMultiplier => 1; - public override LocalisableString Description => "Burn the notes into your memory"; + public override LocalisableString Description => "Burn the notes into your memory."; public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Solid.Camera; - - [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] + [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) @@ -88,15 +86,22 @@ namespace osu.Game.Rulesets.Osu.Mods } } - //Todo: find better way to represent these Enums to the player 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 } } } - From 83aedb193079a016f841298d2e4e68227d3fe58b Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Wed, 12 Oct 2022 12:42:26 +0200 Subject: [PATCH 15/23] Make mod use new Combo, remove pointless test --- .../Mods/TestSceneOsuModFreezeFrame.cs | 40 --------- .../Mods/OsuModFreezeFrame.cs | 89 +++++-------------- 2 files changed, 22 insertions(+), 107 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs 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 - } } } From f67f6cc99ca914b152a355122589900437b6b91d Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Wed, 12 Oct 2022 19:45:08 +0200 Subject: [PATCH 16/23] Fix switch case --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index b21e8a4a5f..a91d7831c3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.Mods { //SliderRepeat wont layer correctly if preempt is changed. case SliderRepeat: - return; + break; default: applyFadeInAdjustment(nested); From e1a8bfa135a103540ad232555fd7f7f33e3eee45 Mon Sep 17 00:00:00 2001 From: Dario Headley Date: Tue, 18 Oct 2022 13:39:40 +0200 Subject: [PATCH 17/23] Fixed approachCircle preempt --- .../Mods/OsuModApproachDifferent.cs | 2 +- .../Mods/OsuModFreezeFrame.cs | 42 +++++++++++++++---- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs b/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs index ec93f19e17..f213d9f193 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1; public override IconUsage? Icon { get; } = FontAwesome.Regular.Circle; - public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles) }; + public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles), typeof(OsuModFreezeFrame) }; [SettingSource("Initial size", "Change the initial size of the approach circle, relative to hit circles.", 0)] public BindableFloat Scale { get; } = new BindableFloat(4) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index a91d7831c3..f2ee93a704 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,17 +1,20 @@ // 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 osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; 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; +using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : Mod, IApplicableToBeatmap, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : Mod, IApplicableToDrawableHitObject, IApplicableToBeatmap + { public override string Name => "Freeze Frame"; @@ -21,16 +24,18 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; + //Alters the transforms of the approach circles, breaking the effects of these mods. + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), /*typeof(OsuModHidden)*/ }; + public override ModType Type => ModType.Fun; - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); - } + //mod breaks normal approach circle preempt + private double approachCircleTimePreempt; public void ApplyToBeatmap(IBeatmap beatmap) { double lastNewComboTime = 0; + approachCircleTimePreempt = beatmap.HitObjects.OfType().FirstOrDefault()!.TimePreempt; foreach (var obj in beatmap.HitObjects.OfType()) { @@ -58,5 +63,28 @@ namespace osu.Game.Rulesets.Osu.Mods } } } + + public void ApplyToDrawableHitObject(DrawableHitObject drawableObject) + { + drawableObject.ApplyCustomUpdateState += (drawableHitObject, _) => + { + if (drawableHitObject is not DrawableHitCircle drawableHitCircle) return; + + var hitCircle = drawableHitCircle.HitObject; + var approachCircle = drawableHitCircle.ApproachCircle; + + approachCircle.ClearTransforms(); + approachCircle.ScaleTo(4); + approachCircle.FadeTo(0); + + using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - approachCircleTimePreempt)) + { + //Redo ApproachCircle animation with correct startTime. + approachCircle.LifetimeStart = hitCircle.StartTime - approachCircleTimePreempt; + approachCircle.FadeTo(1, Math.Min(hitCircle.TimeFadeIn * 2, hitCircle.TimePreempt)); + approachCircle.ScaleTo(1, approachCircleTimePreempt).Then().Expire(); + } + }; + } } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 996ee1cddb..2d7c0c82de 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModFreezeFrame) }; public const double FADE_IN_DURATION_MULTIPLIER = 0.4; public const double FADE_OUT_DURATION_MULTIPLIER = 0.3; From acf3498f83a225ddf10bef957370655944f1e2fd Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 18 Oct 2022 13:49:10 +0200 Subject: [PATCH 18/23] Code Quality --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index f2ee93a704..7395e09d97 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -14,7 +14,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : Mod, IApplicableToDrawableHitObject, IApplicableToBeatmap - { public override string Name => "Freeze Frame"; From 764bc1948fffea55f1fd0eb13150949fdbf88c83 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 18 Oct 2022 14:59:43 +0200 Subject: [PATCH 19/23] remove commented out Incompatible mod --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 7395e09d97..8bf2c89057 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; //Alters the transforms of the approach circles, breaking the effects of these mods. - public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), /*typeof(OsuModHidden)*/ }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), typeof(OsuModHidden) }; public override ModType Type => ModType.Fun; From 3d72ff28c3e09b1e1be93917ceaf2957e34d1adc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:25:38 +0900 Subject: [PATCH 20/23] Add test scene for "Freeze Frame" mod --- .../Mods/TestSceneOsuModFreezeFrame.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs new file mode 100644 index 0000000000..7d7b2d9071 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -0,0 +1,22 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModFreezeFrame : OsuModTestScene + { + [Test] + public void TestFreezeFrame() + { + CreateModTest(new ModTestData + { + Mod = new OsuModFreezeFrame(), + PassCondition = () => true, + Autoplay = false, + }); + } + } +} From 588fc750cdeac7b2b915506f62eb168adb960687 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:26:32 +0900 Subject: [PATCH 21/23] Change approach circles to all appear at the same time, but don't adjust AR --- .../Mods/OsuModFreezeFrame.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 8bf2c89057..2187d33a49 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -29,12 +29,17 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; //mod breaks normal approach circle preempt - private double approachCircleTimePreempt; + private double originalPreempt; public void ApplyToBeatmap(IBeatmap beatmap) { + var firstHitObject = beatmap.HitObjects.OfType().FirstOrDefault(); + if (firstHitObject == null) + return; + double lastNewComboTime = 0; - approachCircleTimePreempt = beatmap.HitObjects.OfType().FirstOrDefault()!.TimePreempt; + + originalPreempt = firstHitObject.TimePreempt; foreach (var obj in beatmap.HitObjects.OfType()) { @@ -72,17 +77,12 @@ namespace osu.Game.Rulesets.Osu.Mods var hitCircle = drawableHitCircle.HitObject; var approachCircle = drawableHitCircle.ApproachCircle; - approachCircle.ClearTransforms(); - approachCircle.ScaleTo(4); - approachCircle.FadeTo(0); + // Reapply scale, ensuring the AR isn't changes due to the new preempt. + approachCircle.ClearTransforms(targetMember: nameof(approachCircle.Scale)); + approachCircle.ScaleTo(4 * (float)(hitCircle.TimePreempt / originalPreempt)); - using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - approachCircleTimePreempt)) - { - //Redo ApproachCircle animation with correct startTime. - approachCircle.LifetimeStart = hitCircle.StartTime - approachCircleTimePreempt; - approachCircle.FadeTo(1, Math.Min(hitCircle.TimeFadeIn * 2, hitCircle.TimePreempt)); - approachCircle.ScaleTo(1, approachCircleTimePreempt).Then().Expire(); - } + using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - hitCircle.TimePreempt)) + approachCircle.ScaleTo(1, hitCircle.TimePreempt).Then().Expire(); }; } } From 279ef556e3c4eb818d40d837809739cf7a8eb8ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:27:26 +0900 Subject: [PATCH 22/23] Fix typon in comment --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 2187d33a49..20d75ab019 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Mods var hitCircle = drawableHitCircle.HitObject; var approachCircle = drawableHitCircle.ApproachCircle; - // Reapply scale, ensuring the AR isn't changes due to the new preempt. + // Reapply scale, ensuring the AR isn't changed due to the new preempt. approachCircle.ClearTransforms(targetMember: nameof(approachCircle.Scale)); approachCircle.ScaleTo(4 * (float)(hitCircle.TimePreempt / originalPreempt)); From f4aae9138bf98ec4475ce14d709dae20be4ca001 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 25 Oct 2022 08:48:45 +0200 Subject: [PATCH 23/23] Remove Incompatibility with HD --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 20d75ab019..bea5d4f5d9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; //Alters the transforms of the approach circles, breaking the effects of these mods. - public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), typeof(OsuModHidden) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent) }; public override ModType Type => ModType.Fun; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 2d7c0c82de..996ee1cddb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModFreezeFrame) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn) }; public const double FADE_IN_DURATION_MULTIPLIER = 0.4; public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;