From 6b1534f5a6e3658d802b19744e5f59c6feae1eb3 Mon Sep 17 00:00:00 2001 From: Jason Won Date: Thu, 14 Oct 2021 18:30:55 -0400 Subject: [PATCH 1/6] Add "ghost" mod for osu --- osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs | 67 +++++++++++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 + 2 files changed, 68 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs new file mode 100644 index 0000000000..d371686d10 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs @@ -0,0 +1,67 @@ +// 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.UI; +using osu.Game.Rulesets.Mods; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Bindables; +using osu.Framework.Localisation; +using osu.Game.Graphics.UserInterface; +using osu.Game.Configuration; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModGhost : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor + { + public override string Name => "Ghost"; + public override string Acronym => "G"; + public override ModType Type => ModType.Fun; + public override IconUsage? Icon => FontAwesome.Solid.Ghost; + public override string Description => "Where's the cursor?"; + public override double ScoreMultiplier => 1; + + private readonly BindableNumber ghostAlpha = new BindableFloat(0); + private BindableNumber currentCombo; + + [SettingSource( + "Hidden at combo", + "The combo count at which the cursor becomes completely hidden", + SettingControlType = typeof(SettingsSlider) + )] + public BindableInt HiddenComboCount { get; } = new BindableInt + { + Default = 10, + Value = 10, + MinValue = 0, + MaxValue = 50, + }; + + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + currentCombo = scoreProcessor.Combo.GetBoundCopy(); + currentCombo.BindValueChanged(combo => + { + float dimFactor = HiddenComboCount.Value == 0 ? 1 : (float)combo.NewValue / HiddenComboCount.Value; + + scoreProcessor.TransformBindableTo(ghostAlpha, 1-dimFactor, 100, Easing.OutQuint); + }, true); + } + + + public virtual void Update(Playfield playfield) + { + playfield.Cursor.Alpha = ghostAlpha.Value; + } + + } + + public class HiddenComboSlider : OsuSliderBar + { + public override LocalisableString TooltipText => Current.Value == 0 ? "always hidden" : base.TooltipText; + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index f4a93a571d..947ecaae82 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -192,6 +192,7 @@ namespace osu.Game.Rulesets.Osu new OsuModBarrelRoll(), new OsuModApproachDifferent(), new OsuModMuted(), + new OsuModGhost(), }; case ModType.System: From 23b50a054beaa41a03c09cb1c6223f85156dafb4 Mon Sep 17 00:00:00 2001 From: Jason Won Date: Thu, 14 Oct 2021 20:50:47 -0400 Subject: [PATCH 2/6] address comments --- osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs | 36 ++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs index d371686d10..7cb9fadf03 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs @@ -3,10 +3,10 @@ using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Mods; -using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Bindables; using osu.Framework.Localisation; +using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Overlays.Settings; @@ -17,14 +17,18 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModGhost : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor { + public const float CURSOR_ALPHA_TRANSITION_DURATION = 100; public override string Name => "Ghost"; - public override string Acronym => "G"; + public override string Acronym => "GS"; public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Ghost; public override string Description => "Where's the cursor?"; public override double ScoreMultiplier => 1; - - private readonly BindableNumber ghostAlpha = new BindableFloat(0); + private double transitionProgress = 0; + private float currentCursorAlpha = 1; + private float startCursorAlpha = 1; + private float targetCursorAlpha = 0; + private BindableNumber currentCombo; [SettingSource( @@ -43,21 +47,25 @@ namespace osu.Game.Rulesets.Osu.Mods public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - currentCombo = scoreProcessor.Combo.GetBoundCopy(); - currentCombo.BindValueChanged(combo => - { - float dimFactor = HiddenComboCount.Value == 0 ? 1 : (float)combo.NewValue / HiddenComboCount.Value; - - scoreProcessor.TransformBindableTo(ghostAlpha, 1-dimFactor, 100, Easing.OutQuint); - }, true); + if (HiddenComboCount.Value != 0) { + currentCombo = scoreProcessor.Combo.GetBoundCopy(); + currentCombo.BindValueChanged(combo => + { + targetCursorAlpha = 1 - (float)combo.NewValue / HiddenComboCount.Value; + startCursorAlpha = currentCursorAlpha; + transitionProgress = 0; + }, true); + } } - public virtual void Update(Playfield playfield) { - playfield.Cursor.Alpha = ghostAlpha.Value; + if (transitionProgress < CURSOR_ALPHA_TRANSITION_DURATION) { + transitionProgress += playfield.Time.Elapsed; + currentCursorAlpha = (float)Interpolation.Lerp(startCursorAlpha, targetCursorAlpha, transitionProgress/CURSOR_ALPHA_TRANSITION_DURATION); + playfield.Cursor.Alpha = currentCursorAlpha; + } } - } public class HiddenComboSlider : OsuSliderBar From 2dfc42dd53ed48e187a94c2c0fcd34c867948566 Mon Sep 17 00:00:00 2001 From: Jason Won Date: Thu, 14 Oct 2021 23:34:43 -0400 Subject: [PATCH 3/6] revert interpolation changes + fix cursor trail --- osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs index 7cb9fadf03..cc8491876b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs @@ -1,12 +1,13 @@ // 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 osu.Game.Rulesets.UI; using osu.Game.Rulesets.Mods; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Bindables; using osu.Framework.Localisation; -using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Overlays.Settings; @@ -24,11 +25,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override IconUsage? Icon => FontAwesome.Solid.Ghost; public override string Description => "Where's the cursor?"; public override double ScoreMultiplier => 1; - private double transitionProgress = 0; - private float currentCursorAlpha = 1; - private float startCursorAlpha = 1; - private float targetCursorAlpha = 0; - + private readonly BindableFloat cursorAlpha = new BindableFloat(); private BindableNumber currentCombo; [SettingSource( @@ -45,26 +42,23 @@ namespace osu.Game.Rulesets.Osu.Mods }; public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - if (HiddenComboCount.Value != 0) { + if (HiddenComboCount.Value != 0) + { currentCombo = scoreProcessor.Combo.GetBoundCopy(); currentCombo.BindValueChanged(combo => { - targetCursorAlpha = 1 - (float)combo.NewValue / HiddenComboCount.Value; - startCursorAlpha = currentCursorAlpha; - transitionProgress = 0; + float targetCursorAlpha = (float)Math.Max(1e-3, 1 - (float)combo.NewValue / HiddenComboCount.Value); + scoreProcessor.TransformBindableTo(cursorAlpha, targetCursorAlpha, CURSOR_ALPHA_TRANSITION_DURATION, Easing.OutQuint); }, true); } } public virtual void Update(Playfield playfield) { - if (transitionProgress < CURSOR_ALPHA_TRANSITION_DURATION) { - transitionProgress += playfield.Time.Elapsed; - currentCursorAlpha = (float)Interpolation.Lerp(startCursorAlpha, targetCursorAlpha, transitionProgress/CURSOR_ALPHA_TRANSITION_DURATION); - playfield.Cursor.Alpha = currentCursorAlpha; - } + playfield.Cursor.Alpha = cursorAlpha.Value; } } From 538d980072aa746519f8e98121f2b2e72d8e75d4 Mon Sep 17 00:00:00 2001 From: Jason Won Date: Fri, 15 Oct 2021 00:22:57 -0400 Subject: [PATCH 4/6] Rename Mod --- .../Mods/{OsuModGhost.cs => OsuModNoScope.cs} | 8 ++++---- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game.Rulesets.Osu/Mods/{OsuModGhost.cs => OsuModNoScope.cs} (90%) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs similarity index 90% rename from osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs rename to osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs index cc8491876b..56c807eacd 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModGhost.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs @@ -16,13 +16,13 @@ using osu.Game.Scoring; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModGhost : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor + public class OsuModNoScope : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor { public const float CURSOR_ALPHA_TRANSITION_DURATION = 100; - public override string Name => "Ghost"; - public override string Acronym => "GS"; + public override string Name => "No Scope"; + public override string Acronym => "NS"; public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Solid.Ghost; + public override IconUsage? Icon => FontAwesome.Solid.EyeSlash; public override string Description => "Where's the cursor?"; public override double ScoreMultiplier => 1; private readonly BindableFloat cursorAlpha = new BindableFloat(); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 947ecaae82..ee4712c3b8 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Osu new OsuModBarrelRoll(), new OsuModApproachDifferent(), new OsuModMuted(), - new OsuModGhost(), + new OsuModNoScope(), }; case ModType.System: From 6a80a417bdc7f8520bcc76577d93629ec8a2991e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Oct 2021 14:25:50 +0900 Subject: [PATCH 5/6] Use `Interpolation.Lerp` instead of transforms Better handles cases where the combo may be changing faster than the transition length. --- osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs | 27 +++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs index 56c807eacd..09870f2758 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Bindables; using osu.Framework.Localisation; +using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Overlays.Settings; @@ -19,15 +20,18 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModNoScope : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor { public const float CURSOR_ALPHA_TRANSITION_DURATION = 100; + public override string Name => "No Scope"; public override string Acronym => "NS"; public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.EyeSlash; public override string Description => "Where's the cursor?"; public override double ScoreMultiplier => 1; - private readonly BindableFloat cursorAlpha = new BindableFloat(); + private BindableNumber currentCombo; + private float targetAlpha; + [SettingSource( "Hidden at combo", "The combo count at which the cursor becomes completely hidden", @@ -43,22 +47,25 @@ namespace osu.Game.Rulesets.Osu.Mods public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + /// + /// Slightly higher than the cutoff for . + /// + private const float min_alpha = 0.0002f; + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - if (HiddenComboCount.Value != 0) + if (HiddenComboCount.Value == 0) return; + + currentCombo = scoreProcessor.Combo.GetBoundCopy(); + currentCombo.BindValueChanged(combo => { - currentCombo = scoreProcessor.Combo.GetBoundCopy(); - currentCombo.BindValueChanged(combo => - { - float targetCursorAlpha = (float)Math.Max(1e-3, 1 - (float)combo.NewValue / HiddenComboCount.Value); - scoreProcessor.TransformBindableTo(cursorAlpha, targetCursorAlpha, CURSOR_ALPHA_TRANSITION_DURATION, Easing.OutQuint); - }, true); - } + targetAlpha = Math.Max(min_alpha, 1 - (float)combo.NewValue / HiddenComboCount.Value); + }, true); } public virtual void Update(Playfield playfield) { - playfield.Cursor.Alpha = cursorAlpha.Value; + playfield.Cursor.Alpha = (float)Interpolation.Lerp(playfield.Cursor.Alpha, targetAlpha, Math.Clamp(playfield.Time.Elapsed / CURSOR_ALPHA_TRANSITION_DURATION, 0, 1)); } } From 3a7eb7dd25f8e2da74684ec3395d79f5a917e92f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Oct 2021 14:27:20 +0900 Subject: [PATCH 6/6] Make const private --- osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs index 09870f2758..c48cbd9992 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNoScope.cs @@ -19,7 +19,12 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModNoScope : Mod, IUpdatableByPlayfield, IApplicableToScoreProcessor { - public const float CURSOR_ALPHA_TRANSITION_DURATION = 100; + /// + /// Slightly higher than the cutoff for . + /// + private const float min_alpha = 0.0002f; + + private const float transition_duration = 100; public override string Name => "No Scope"; public override string Acronym => "NS"; @@ -47,11 +52,6 @@ namespace osu.Game.Rulesets.Osu.Mods public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; - /// - /// Slightly higher than the cutoff for . - /// - private const float min_alpha = 0.0002f; - public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { if (HiddenComboCount.Value == 0) return; @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Mods public virtual void Update(Playfield playfield) { - playfield.Cursor.Alpha = (float)Interpolation.Lerp(playfield.Cursor.Alpha, targetAlpha, Math.Clamp(playfield.Time.Elapsed / CURSOR_ALPHA_TRANSITION_DURATION, 0, 1)); + playfield.Cursor.Alpha = (float)Interpolation.Lerp(playfield.Cursor.Alpha, targetAlpha, Math.Clamp(playfield.Time.Elapsed / transition_duration, 0, 1)); } }