diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index b8a844cb86..4228b86795 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -106,6 +106,12 @@ namespace osu.Game.Rulesets.Catch new CatchModFlashlight(), }; + case ModType.Conversion: + return new Mod[] + { + new CatchModDifficultyAdjust(), + }; + case ModType.Automation: return new Mod[] { diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs new file mode 100644 index 0000000000..4c0f5d510e --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -0,0 +1,49 @@ +// 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.Configuration; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModDifficultyAdjust : ModDifficultyAdjust + { + [SettingSource("Fruit Size", "Override a beatmap's set CS.")] + public BindableNumber CircleSize { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + [SettingSource("Approach Rate", "Override a beatmap's set AR.")] + public BindableNumber ApproachRate { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + protected override void TransferSettings(BeatmapDifficulty difficulty) + { + base.TransferSettings(difficulty); + + CircleSize.Value = CircleSize.Default = difficulty.CircleSize; + ApproachRate.Value = ApproachRate.Default = difficulty.ApproachRate; + } + + protected override void ApplySettings(BeatmapDifficulty difficulty) + { + base.ApplySettings(difficulty); + + difficulty.CircleSize = CircleSize.Value; + difficulty.ApproachRate = ApproachRate.Value; + } + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index bf630cf892..9ab588c550 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -151,6 +151,7 @@ namespace osu.Game.Rulesets.Mania new ManiaModRandom(), new ManiaModDualStages(), new ManiaModMirror(), + new ManiaModDifficultyAdjust(), }; case ModType.Automation: diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDifficultyAdjust.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDifficultyAdjust.cs new file mode 100644 index 0000000000..0817f8f9fc --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDifficultyAdjust.cs @@ -0,0 +1,11 @@ +// 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.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModDifficultyAdjust : ModDifficultyAdjust + { + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs new file mode 100644 index 0000000000..0514e2ab34 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -0,0 +1,49 @@ +// 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.Configuration; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModDifficultyAdjust : ModDifficultyAdjust + { + [SettingSource("Circle Size", "Override a beatmap's set CS.")] + public BindableNumber CircleSize { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + [SettingSource("Approach Rate", "Override a beatmap's set AR.")] + public BindableNumber ApproachRate { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + protected override void TransferSettings(BeatmapDifficulty difficulty) + { + base.TransferSettings(difficulty); + + CircleSize.Value = CircleSize.Default = difficulty.CircleSize; + ApproachRate.Value = ApproachRate.Default = difficulty.ApproachRate; + } + + protected override void ApplySettings(BeatmapDifficulty difficulty) + { + base.ApplySettings(difficulty); + + difficulty.CircleSize = CircleSize.Value; + difficulty.ApproachRate = ApproachRate.Value; + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 27af615935..a42402151f 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -130,6 +130,7 @@ namespace osu.Game.Rulesets.Osu return new Mod[] { new OsuModTarget(), + new OsuModDifficultyAdjust(), }; case ModType.Automation: diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs new file mode 100644 index 0000000000..56a73ad7df --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs @@ -0,0 +1,11 @@ +// 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.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModDifficultyAdjust : ModDifficultyAdjust + { + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index ca7ab30867..a055c29efe 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -105,6 +105,12 @@ namespace osu.Game.Rulesets.Taiko new TaikoModFlashlight(), }; + case ModType.Conversion: + return new Mod[] + { + new TaikoModDifficultyAdjust(), + }; + case ModType.Automation: return new Mod[] { diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs new file mode 100644 index 0000000000..224fc78508 --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -0,0 +1,81 @@ +// 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.Beatmaps; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Sprites; +using System; +using osu.Game.Configuration; + +namespace osu.Game.Rulesets.Mods +{ + public abstract class ModDifficultyAdjust : Mod, IApplicableToDifficulty + { + public override string Name => @"Difficulty Adjust"; + + public override string Description => @"Override a beatmap's difficulty settings."; + + public override string Acronym => "DA"; + + public override ModType Type => ModType.Conversion; + + public override IconUsage Icon => FontAwesome.Solid.Hammer; + + public override double ScoreMultiplier => 1.0; + + public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; + + [SettingSource("Drain Rate", "Override a beatmap's set HP.")] + public BindableNumber DrainRate { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + [SettingSource("Overall Difficulty", "Override a beatmap's set OD.")] + public BindableNumber OverallDifficulty { get; } = new BindableFloat + { + Precision = 0.1f, + MinValue = 1, + MaxValue = 10, + Default = 5, + Value = 5, + }; + + private BeatmapDifficulty difficulty; + + public void ApplyToDifficulty(BeatmapDifficulty difficulty) + { + if (this.difficulty == null || this.difficulty.ID != difficulty.ID) + { + this.difficulty = difficulty; + TransferSettings(difficulty); + } + else + ApplySettings(difficulty); + } + + /// + /// Transfer initial settings from the beatmap to settings. + /// + /// The beatmap's initial values. + protected virtual void TransferSettings(BeatmapDifficulty difficulty) + { + DrainRate.Value = DrainRate.Default = difficulty.DrainRate; + OverallDifficulty.Value = OverallDifficulty.Default = difficulty.OverallDifficulty; + } + + /// + /// Apply all custom settings to the provided beatmap. + /// + /// The beatmap to have settings applied. + protected virtual void ApplySettings(BeatmapDifficulty difficulty) + { + difficulty.DrainRate = DrainRate.Value; + difficulty.OverallDifficulty = OverallDifficulty.Value; + } + } +} diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index a55ebc51d6..7a34b2de3c 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyReduction; public override double ScoreMultiplier => 0.5; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModHardRock) }; + public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) }; private int retries = 2; diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index 2044cbeae2..2bcac3e4a9 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods public override IconUsage Icon => OsuIcon.ModHardrock; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Everything just got a bit harder..."; - public override Type[] IncompatibleMods => new[] { typeof(ModEasy) }; + public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModDifficultyAdjust) }; public void ApplyToDifficulty(BeatmapDifficulty difficulty) {