diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHealthProcessor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuLegacyHealthProcessor.cs similarity index 86% rename from osu.Game.Rulesets.Osu.Tests/TestSceneOsuHealthProcessor.cs rename to osu.Game.Rulesets.Osu.Tests/TestSceneOsuLegacyHealthProcessor.cs index 16f28c0212..a7ae06a9ce 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHealthProcessor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuLegacyHealthProcessor.cs @@ -10,12 +10,12 @@ namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneOsuHealthProcessor + public class TestSceneOsuLegacyHealthProcessor { [Test] public void TestNoBreak() { - OsuHealthProcessor hp = new OsuHealthProcessor(-1000); + OsuLegacyHealthProcessor hp = new OsuLegacyHealthProcessor(-1000); hp.ApplyBeatmap(new Beatmap { HitObjects = @@ -31,7 +31,7 @@ public void TestNoBreak() [Test] public void TestSingleBreak() { - OsuHealthProcessor hp = new OsuHealthProcessor(-1000); + OsuLegacyHealthProcessor hp = new OsuLegacyHealthProcessor(-1000); hp.ApplyBeatmap(new Beatmap { HitObjects = @@ -51,7 +51,7 @@ public void TestSingleBreak() [Test] public void TestOverlappingBreak() { - OsuHealthProcessor hp = new OsuHealthProcessor(-1000); + OsuLegacyHealthProcessor hp = new OsuLegacyHealthProcessor(-1000); hp.ApplyBeatmap(new Beatmap { HitObjects = @@ -72,7 +72,7 @@ public void TestOverlappingBreak() [Test] public void TestSequentialBreak() { - OsuHealthProcessor hp = new OsuHealthProcessor(-1000); + OsuLegacyHealthProcessor hp = new OsuLegacyHealthProcessor(-1000); hp.ApplyBeatmap(new Beatmap { HitObjects = diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModClassic.cs b/osu.Game.Rulesets.Osu/Mods/OsuModClassic.cs index f20f95b384..10d7af5e58 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModClassic.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModClassic.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModClassic : ModClassic, IApplicableToHitObject, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset + public class OsuModClassic : ModClassic, IApplicableToHitObject, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset, IApplicableHealthProcessor { public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModStrictTracking)).ToArray(); @@ -34,6 +34,9 @@ public class OsuModClassic : ModClassic, IApplicableToHitObject, IApplicableToDr [SettingSource("Fade out hit circles earlier", "Make hit circles fade out into a miss, rather than after it.")] public Bindable FadeHitCircleEarly { get; } = new Bindable(true); + [SettingSource("Classic health", "More closely resembles the original HP drain mechanics.")] + public Bindable ClassicHealth { get; } = new Bindable(true); + private bool usingHiddenFading; public void ApplyToHitObject(HitObject hitObject) @@ -115,5 +118,7 @@ private void applyEarlyFading(DrawableHitCircle circle) } }; } + + public HealthProcessor? CreateHealthProcessor(double drainStartTime) => ClassicHealth.Value ? new OsuLegacyHealthProcessor(drainStartTime) : null; } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 35cbfa3790..e53f20277b 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -48,8 +48,6 @@ public class OsuRuleset : Ruleset, ILegacyRuleset public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(); - public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new OsuHealthProcessor(drainStartTime); - public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap, this); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuHealthProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuLegacyHealthProcessor.cs similarity index 95% rename from osu.Game.Rulesets.Osu/Scoring/OsuHealthProcessor.cs rename to osu.Game.Rulesets.Osu/Scoring/OsuLegacyHealthProcessor.cs index 7025a7be65..e383e82b86 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuHealthProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuLegacyHealthProcessor.cs @@ -10,9 +10,9 @@ namespace osu.Game.Rulesets.Osu.Scoring { - public partial class OsuHealthProcessor : LegacyDrainingHealthProcessor + public partial class OsuLegacyHealthProcessor : LegacyDrainingHealthProcessor { - public OsuHealthProcessor(double drainStartTime) + public OsuLegacyHealthProcessor(double drainStartTime) : base(drainStartTime) { } diff --git a/osu.Game/Rulesets/Mods/IApplicableHealthProcessor.cs b/osu.Game/Rulesets/Mods/IApplicableHealthProcessor.cs new file mode 100644 index 0000000000..be46828069 --- /dev/null +++ b/osu.Game/Rulesets/Mods/IApplicableHealthProcessor.cs @@ -0,0 +1,18 @@ +// 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.Scoring; + +namespace osu.Game.Rulesets.Mods +{ + /// + /// Interface for a that provides its own health processor. + /// + public interface IApplicableHealthProcessor + { + /// + /// Creates the . May be null to use the ruleset default. + /// + HealthProcessor? CreateHealthProcessor(double drainStartTime); + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1c97efcff7..cc08079d88 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -227,7 +227,8 @@ private void load(OsuConfigManager config, OsuGameBase game, CancellationToken c dependencies.CacheAs(ScoreProcessor); - HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); + HealthProcessor = gameplayMods.OfType().FirstOrDefault()?.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); + HealthProcessor ??= ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor.ApplyBeatmap(playableBeatmap); dependencies.CacheAs(HealthProcessor);