From 0794fc61a0935274beed82de91ef780c4b1d34f2 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Fri, 11 Oct 2024 18:38:53 -0400 Subject: [PATCH 01/11] Initial Implementation (working, unsafe handling of cursor position) --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 106 +++++++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 12 +++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs new file mode 100644 index 0000000000..193b0142df --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -0,0 +1,106 @@ +// 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.Diagnostics; +using osu.Framework.Bindables; +using osu.Framework.Localisation; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.UI; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Screens.Play; +using osu.Game.Rulesets.Osu.UI.Cursor; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfield, IApplicableToPlayer + { + public override string Name => "Bloom"; + public override string Acronym => "BM"; + public override ModType Type => ModType.Fun; + public override LocalisableString Description => "The cursor blooms into a.. larger cursor!"; + public override double ScoreMultiplier => 1; + protected const float MIN_SIZE = 1; + protected const float TRANSITION_DURATION = 100; + public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(OsuModObjectScaleTween), typeof(OsuModTouchDevice), typeof(OsuModAutopilot) }; + + + protected readonly BindableNumber CurrentCombo = new BindableInt(); + protected readonly IBindable IsBreakTime = new Bindable(); + protected float ComboBasedSize; + + + [SettingSource( + "Max Size at Combo", + "The combo count at which the cursor reaches its maximum size", + SettingControlType = typeof(SettingsSlider) + )] + public BindableInt MaxSizeComboCount { get; } = new BindableInt(50) + { + MinValue = 0, + MaxValue = 100, + }; + [SettingSource( + "Final Size Multiplier", + "The multiplier applied to cursor size when combo reaches maximum", + SettingControlType = typeof(SettingsSlider>) + )] + public BindableFloat MaxMulti { get; } = new BindableFloat(10f) + { + MinValue = 5f, + MaxValue = 15f, + Precision = 0.5f, + }; + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + public void ApplyToPlayer(Player player) + { + IsBreakTime.BindTo(player.IsBreakTime); + } + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + if (MaxSizeComboCount.Value == 0) return; + + CurrentCombo.BindTo(scoreProcessor.Combo); + CurrentCombo.BindValueChanged(combo => + { + ComboBasedSize = Math.Min(MaxMulti.Value, 10 * ((float)combo.NewValue / MaxSizeComboCount.Value)); + ComboBasedSize = Math.Max(ComboBasedSize, MIN_SIZE); + }, true + ); + } + public void Update(Playfield playfield) + //terrible terrible handling on making sure cursor position stays accurate, will fix + { + bool beBaseSize = IsBreakTime.Value; + var osuPlayfield = (OsuPlayfield)playfield; + Debug.Assert(osuPlayfield.Cursor != null); + var realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; + realCursor.isBloom = true; + if (beBaseSize) + { + realCursor.ComboSize = 1; + } + else + { + realCursor.ComboSize = ComboBasedSize; + } + } + + + + + } + public partial class MaxSizeSlider : RoundedSliderBar + { + public override LocalisableString TooltipText => Current.Value == 0 ? "always at max size" : base.TooltipText; + } + +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 2f928aaefa..25b1dd9b12 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -214,7 +214,8 @@ public override IEnumerable GetModsFor(ModType type) new OsuModFreezeFrame(), new OsuModBubbles(), new OsuModSynesthesia(), - new OsuModDepth() + new OsuModDepth(), + new OsuModBloom() }; case ModType.System: diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 0bb316e0aa..75a38826ad 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -39,6 +39,8 @@ public partial class OsuCursor : SkinReloadableDrawable public IBindable CursorScale => cursorScale; private readonly Bindable cursorScale = new BindableFloat(1); + public bool isBloom; + public float ComboSize; private Bindable userCursorScale = null!; private Bindable autoCursorScale = null!; @@ -68,6 +70,7 @@ private void load() autoCursorScale.ValueChanged += _ => cursorScale.Value = CalculateCursorScale(); cursorScale.BindValueChanged(e => cursorScaleContainer.Scale = new Vector2(e.NewValue), true); + isBloom = false; } protected override void LoadComplete() @@ -75,6 +78,15 @@ protected override void LoadComplete() base.LoadComplete(); cursorScale.Value = CalculateCursorScale(); } + protected override void Update() + //this should not exist will implement sane fix + { + base.Update(); + if (isBloom) + { + cursorScale.Value = ComboSize; + } + } protected virtual Drawable CreateCursorContent() => cursorScaleContainer = new Container { From 4d367515dc2fbb8200b42ceba48cb33bb3bcf21c Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Fri, 11 Oct 2024 21:52:13 -0400 Subject: [PATCH 02/11] Smoother size changing using linear interpolation --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index 193b0142df..a9026e470b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -17,6 +17,7 @@ using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Rulesets.Osu.UI.Cursor; +using osu.Framework.Utils; namespace osu.Game.Rulesets.Osu.Mods { @@ -84,13 +85,14 @@ public void Update(Playfield playfield) Debug.Assert(osuPlayfield.Cursor != null); var realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; realCursor.isBloom = true; + float currentCombSize = (float)Interpolation.Lerp(osuPlayfield.Cursor.Scale.X, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); if (beBaseSize) { realCursor.ComboSize = 1; } else { - realCursor.ComboSize = ComboBasedSize; + realCursor.ComboSize = currentCombSize; } } From 1a142ff94448dc93c7f88ad89493c15fc6159248 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Mon, 14 Oct 2024 01:54:02 -0400 Subject: [PATCH 03/11] minor changes --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 3 ++- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index a9026e470b..8ed0e60445 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -85,7 +85,8 @@ public void Update(Playfield playfield) Debug.Assert(osuPlayfield.Cursor != null); var realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; realCursor.isBloom = true; - float currentCombSize = (float)Interpolation.Lerp(osuPlayfield.Cursor.Scale.X, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); + float currentCombSize = (float)Interpolation.Lerp(realCursor.ComboSize, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); + Console.WriteLine(ComboBasedSize + " " + currentCombSize); if (beBaseSize) { realCursor.ComboSize = 1; diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 75a38826ad..f3a6b0da3d 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -17,6 +17,7 @@ using osu.Game.Skinning; using osuTK; using osuTK.Graphics; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Osu.UI.Cursor { @@ -70,13 +71,13 @@ private void load() autoCursorScale.ValueChanged += _ => cursorScale.Value = CalculateCursorScale(); cursorScale.BindValueChanged(e => cursorScaleContainer.Scale = new Vector2(e.NewValue), true); - isBloom = false; } protected override void LoadComplete() { base.LoadComplete(); cursorScale.Value = CalculateCursorScale(); + isBloom = false; } protected override void Update() //this should not exist will implement sane fix From bd71da012ad82cf828997e0cf3899789599315ea Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Tue, 15 Oct 2024 02:14:03 -0400 Subject: [PATCH 04/11] Refactors handling of scale to a function --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 13 +++++-------- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 17 ++++------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index 8ed0e60445..a249aec35c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -78,22 +78,19 @@ public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) ); } public void Update(Playfield playfield) - //terrible terrible handling on making sure cursor position stays accurate, will fix { bool beBaseSize = IsBreakTime.Value; - var osuPlayfield = (OsuPlayfield)playfield; + OsuPlayfield osuPlayfield = (OsuPlayfield)playfield; Debug.Assert(osuPlayfield.Cursor != null); - var realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; - realCursor.isBloom = true; - float currentCombSize = (float)Interpolation.Lerp(realCursor.ComboSize, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); - Console.WriteLine(ComboBasedSize + " " + currentCombSize); + OsuCursor realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; + float currentCombSize = (float)Interpolation.Lerp(realCursor.CursorScale.Value, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); if (beBaseSize) { - realCursor.ComboSize = 1; + realCursor.UpdateSize(1); } else { - realCursor.ComboSize = currentCombSize; + realCursor.UpdateSize(currentCombSize); } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index f3a6b0da3d..a3a4f8a547 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -17,7 +17,6 @@ using osu.Game.Skinning; using osuTK; using osuTK.Graphics; -using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Osu.UI.Cursor { @@ -40,8 +39,6 @@ public partial class OsuCursor : SkinReloadableDrawable public IBindable CursorScale => cursorScale; private readonly Bindable cursorScale = new BindableFloat(1); - public bool isBloom; - public float ComboSize; private Bindable userCursorScale = null!; private Bindable autoCursorScale = null!; @@ -77,16 +74,6 @@ protected override void LoadComplete() { base.LoadComplete(); cursorScale.Value = CalculateCursorScale(); - isBloom = false; - } - protected override void Update() - //this should not exist will implement sane fix - { - base.Update(); - if (isBloom) - { - cursorScale.Value = ComboSize; - } } protected virtual Drawable CreateCursorContent() => cursorScaleContainer = new Container @@ -113,6 +100,10 @@ protected virtual float CalculateCursorScale() return scale; } + public void UpdateSize(float size) + { + cursorScale.Value = size; + } protected override void SkinChanged(ISkinSource skin) { From 86a5760ef490bbb548e9539224814cd2eaebdcd3 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Tue, 15 Oct 2024 02:23:41 -0400 Subject: [PATCH 05/11] Remove handling for zero as MaxSizeComboCount, set lower limit as 5 --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index a249aec35c..a3cd91b49e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -41,11 +41,11 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie [SettingSource( "Max Size at Combo", "The combo count at which the cursor reaches its maximum size", - SettingControlType = typeof(SettingsSlider) + SettingControlType = typeof(SettingsSlider>) )] public BindableInt MaxSizeComboCount { get; } = new BindableInt(50) { - MinValue = 0, + MinValue = 5, MaxValue = 100, }; [SettingSource( @@ -93,14 +93,5 @@ public void Update(Playfield playfield) realCursor.UpdateSize(currentCombSize); } } - - - - } - public partial class MaxSizeSlider : RoundedSliderBar - { - public override LocalisableString TooltipText => Current.Value == 0 ? "always at max size" : base.TooltipText; - } - } From f6566f91571addd8e52ea7d8b265859822eea96b Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Tue, 15 Oct 2024 15:37:05 -0400 Subject: [PATCH 06/11] Code quality touch-ups --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 16 +++++++++------- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index a3cd91b49e..eef9f0590d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -1,8 +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.Diagnostics; using osu.Framework.Bindables; @@ -26,18 +24,16 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie public override string Name => "Bloom"; public override string Acronym => "BM"; public override ModType Type => ModType.Fun; - public override LocalisableString Description => "The cursor blooms into a.. larger cursor!"; + public override LocalisableString Description => "The cursor blooms into.. a larger cursor!"; public override double ScoreMultiplier => 1; protected const float MIN_SIZE = 1; protected const float TRANSITION_DURATION = 100; public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(OsuModObjectScaleTween), typeof(OsuModTouchDevice), typeof(OsuModAutopilot) }; - protected readonly BindableNumber CurrentCombo = new BindableInt(); protected readonly IBindable IsBreakTime = new Bindable(); protected float ComboBasedSize; - [SettingSource( "Max Size at Combo", "The combo count at which the cursor reaches its maximum size", @@ -48,6 +44,7 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie MinValue = 5, MaxValue = 100, }; + [SettingSource( "Final Size Multiplier", "The multiplier applied to cursor size when combo reaches maximum", @@ -59,7 +56,9 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie MaxValue = 15f, Precision = 0.5f, }; + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + public void ApplyToPlayer(Player player) { IsBreakTime.BindTo(player.IsBreakTime); @@ -74,20 +73,23 @@ public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { ComboBasedSize = Math.Min(MaxMulti.Value, 10 * ((float)combo.NewValue / MaxSizeComboCount.Value)); ComboBasedSize = Math.Max(ComboBasedSize, MIN_SIZE); - }, true - ); + }, true); } + public void Update(Playfield playfield) { bool beBaseSize = IsBreakTime.Value; OsuPlayfield osuPlayfield = (OsuPlayfield)playfield; Debug.Assert(osuPlayfield.Cursor != null); + OsuCursor realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; float currentCombSize = (float)Interpolation.Lerp(realCursor.CursorScale.Value, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); + if (beBaseSize) { realCursor.UpdateSize(1); } + else { realCursor.UpdateSize(currentCombSize); diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index a3a4f8a547..545cd15d32 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -100,6 +100,7 @@ protected virtual float CalculateCursorScale() return scale; } + public void UpdateSize(float size) { cursorScale.Value = size; From bf970afddb92d45c30749630e52d6f42dd1ba2b7 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Tue, 15 Oct 2024 16:27:05 -0400 Subject: [PATCH 07/11] Formatting --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index eef9f0590d..a132e1d4c8 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -89,7 +89,6 @@ public void Update(Playfield playfield) { realCursor.UpdateSize(1); } - else { realCursor.UpdateSize(currentCombSize); From 9e1af18ac6aa7bec1021f91cb8e3954c2e304df5 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Wed, 16 Oct 2024 20:37:59 -0400 Subject: [PATCH 08/11] Fixed improper handling of size calculation when the max multiplier was changed in mod settings --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index a132e1d4c8..e1b05fa84b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -66,13 +66,10 @@ public void ApplyToPlayer(Player player) public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - if (MaxSizeComboCount.Value == 0) return; - CurrentCombo.BindTo(scoreProcessor.Combo); CurrentCombo.BindValueChanged(combo => { - ComboBasedSize = Math.Min(MaxMulti.Value, 10 * ((float)combo.NewValue / MaxSizeComboCount.Value)); - ComboBasedSize = Math.Max(ComboBasedSize, MIN_SIZE); + ComboBasedSize = Math.Clamp(MaxMulti.Value * ((float)combo.NewValue / MaxSizeComboCount.Value), MIN_SIZE, MaxMulti.Value); }, true); } From af4a3785e91725d1aae10f141e4113807d879a4b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2024 14:38:34 +0900 Subject: [PATCH 09/11] Fix up code quality and isolate scale better --- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 38 ++++++++------------ osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 14 ++++---- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index e1b05fa84b..425db55c6e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -2,20 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Localisation; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.UI; -using osu.Game.Rulesets.UI; +using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; -using osu.Game.Rulesets.Osu.UI.Cursor; -using osu.Framework.Utils; namespace osu.Game.Rulesets.Osu.Mods { @@ -32,10 +30,11 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie protected readonly BindableNumber CurrentCombo = new BindableInt(); protected readonly IBindable IsBreakTime = new Bindable(); - protected float ComboBasedSize; + + private float currentSize; [SettingSource( - "Max Size at Combo", + "Max size at combo", "The combo count at which the cursor reaches its maximum size", SettingControlType = typeof(SettingsSlider>) )] @@ -46,11 +45,11 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie }; [SettingSource( - "Final Size Multiplier", + "Final size multiplier", "The multiplier applied to cursor size when combo reaches maximum", SettingControlType = typeof(SettingsSlider>) )] - public BindableFloat MaxMulti { get; } = new BindableFloat(10f) + public BindableFloat MaxCursorSize { get; } = new BindableFloat(10f) { MinValue = 5f, MaxValue = 15f, @@ -69,27 +68,18 @@ public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) CurrentCombo.BindTo(scoreProcessor.Combo); CurrentCombo.BindValueChanged(combo => { - ComboBasedSize = Math.Clamp(MaxMulti.Value * ((float)combo.NewValue / MaxSizeComboCount.Value), MIN_SIZE, MaxMulti.Value); + currentSize = Math.Clamp(MaxCursorSize.Value * ((float)combo.NewValue / MaxSizeComboCount.Value), MIN_SIZE, MaxCursorSize.Value); }, true); } public void Update(Playfield playfield) { - bool beBaseSize = IsBreakTime.Value; - OsuPlayfield osuPlayfield = (OsuPlayfield)playfield; - Debug.Assert(osuPlayfield.Cursor != null); + OsuCursor cursor = (OsuCursor)(playfield.Cursor!.ActiveCursor); - OsuCursor realCursor = (OsuCursor)osuPlayfield.Cursor.ActiveCursor; - float currentCombSize = (float)Interpolation.Lerp(realCursor.CursorScale.Value, ComboBasedSize, Math.Clamp(osuPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); - - if (beBaseSize) - { - realCursor.UpdateSize(1); - } + if (IsBreakTime.Value) + cursor.ModScaleAdjust.Value = 1; else - { - realCursor.UpdateSize(currentCombSize); - } + cursor.ModScaleAdjust.Value = (float)Interpolation.Lerp(cursor.ModScaleAdjust.Value, currentSize, Math.Clamp(cursor.Time.Elapsed / TRANSITION_DURATION, 0, 1)); } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 545cd15d32..c2f7d84f5e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -38,6 +38,11 @@ public partial class OsuCursor : SkinReloadableDrawable public IBindable CursorScale => cursorScale; + /// + /// Mods which want to adjust cursor size should do so via this bindable. + /// + public readonly Bindable ModScaleAdjust = new Bindable(1); + private readonly Bindable cursorScale = new BindableFloat(1); private Bindable userCursorScale = null!; @@ -67,6 +72,8 @@ private void load() autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); autoCursorScale.ValueChanged += _ => cursorScale.Value = CalculateCursorScale(); + ModScaleAdjust.ValueChanged += _ => cursorScale.Value = CalculateCursorScale(); + cursorScale.BindValueChanged(e => cursorScaleContainer.Scale = new Vector2(e.NewValue), true); } @@ -90,7 +97,7 @@ protected override void LoadComplete() protected virtual float CalculateCursorScale() { - float scale = userCursorScale.Value; + float scale = userCursorScale.Value * ModScaleAdjust.Value; if (autoCursorScale.Value && state != null) { @@ -101,11 +108,6 @@ protected virtual float CalculateCursorScale() return scale; } - public void UpdateSize(float size) - { - cursorScale.Value = size; - } - protected override void SkinChanged(ISkinSource skin) { cursorExpand = skin.GetConfig(OsuSkinConfiguration.CursorExpand)?.Value ?? true; From 46f59907319b870fae52e017239f109c64dad393 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Wed, 13 Nov 2024 21:12:29 -0500 Subject: [PATCH 10/11] Ensure mod incompatibility consistency across files --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 3 ++- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs | 2 ++ osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index b45b4fea13..8e9b14edeb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -32,7 +32,8 @@ public class OsuModAutopilot : Mod, IUpdatableByPlayfield, IApplicableToDrawable typeof(ModAutoplay), typeof(OsuModMagnetised), typeof(OsuModRepel), - typeof(ModTouchDevice) + typeof(ModTouchDevice), + typeof(OsuModBloom) }; private OsuInputManager inputManager = null!; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index 425db55c6e..442465bf29 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -26,7 +26,7 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie public override double ScoreMultiplier => 1; protected const float MIN_SIZE = 1; protected const float TRANSITION_DURATION = 100; - public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(OsuModObjectScaleTween), typeof(OsuModTouchDevice), typeof(OsuModAutopilot) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(OsuModObjectScaleTween), typeof(ModTouchDevice), typeof(OsuModAutopilot) }; protected readonly BindableNumber CurrentCombo = new BindableInt(); protected readonly IBindable IsBreakTime = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index 5a6cc50082..3009530b50 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods public partial class OsuModFlashlight : ModFlashlight, IApplicableToDrawableHitObject { public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModBlinds)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModBloom), typeof(OsuModBlinds) }).ToArray(); private const double default_follow_delay = 120; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs index d1bbae8e1a..57d540a7d4 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs @@ -20,6 +20,8 @@ public class OsuModNoScope : ModNoScope, IUpdatableByPlayfield, IApplicableToBea { public override LocalisableString Description => "Where's the cursor?"; + public override Type[] IncompatibleMods => new[] { typeof(OsuModBloom) }; + private PeriodTracker spinnerPeriods = null!; public override BindableInt HiddenComboCount { get; } = new BindableInt(10) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs b/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs index 1df344648a..a851ba0bbd 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs @@ -26,7 +26,7 @@ public abstract class OsuModObjectScaleTween : ModWithVisibilityAdjustment, IHid protected virtual float EndScale => 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween), typeof(OsuModDepth) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween), typeof(OsuModDepth), typeof(OsuModBloom) }; protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs index 917685cdad..a364190a00 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModTouchDevice : ModTouchDevice { - public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray(); public override bool Ranked => UsesDefaultConfiguration; } } From ef9296f3ada2fe29537373795c3fd98415454193 Mon Sep 17 00:00:00 2001 From: jhk2601 Date: Thu, 14 Nov 2024 14:12:21 -0500 Subject: [PATCH 11/11] Allow Autopilot and Grow/Deflate compatibility --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 3 +-- osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 8e9b14edeb..b45b4fea13 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -32,8 +32,7 @@ public class OsuModAutopilot : Mod, IUpdatableByPlayfield, IApplicableToDrawable typeof(ModAutoplay), typeof(OsuModMagnetised), typeof(OsuModRepel), - typeof(ModTouchDevice), - typeof(OsuModBloom) + typeof(ModTouchDevice) }; private OsuInputManager inputManager = null!; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs index 442465bf29..c674074dc6 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBloom.cs @@ -26,7 +26,7 @@ public class OsuModBloom : Mod, IApplicableToScoreProcessor, IUpdatableByPlayfie public override double ScoreMultiplier => 1; protected const float MIN_SIZE = 1; protected const float TRANSITION_DURATION = 100; - public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(OsuModObjectScaleTween), typeof(ModTouchDevice), typeof(OsuModAutopilot) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModFlashlight), typeof(OsuModNoScope), typeof(ModTouchDevice) }; protected readonly BindableNumber CurrentCombo = new BindableInt(); protected readonly IBindable IsBreakTime = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs b/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs index a851ba0bbd..1df344648a 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModObjectScaleTween.cs @@ -26,7 +26,7 @@ public abstract class OsuModObjectScaleTween : ModWithVisibilityAdjustment, IHid protected virtual float EndScale => 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween), typeof(OsuModDepth), typeof(OsuModBloom) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween), typeof(OsuModDepth) }; protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) {