diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 42d7d242ad32..76ecf05af1e4 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -11,6 +11,7 @@ using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHidden : ModHidden, IHidesApproachCircles, IApplicableToHealthProcessor, IUpdatableByPlayfield, IApplicableToScoreProcessor + public class OsuModHidden : ModHidden, IHidesApproachCircles, IUpdatableByPlayfield, IApplicableToScoreProcessor { [SettingSource("Only fade approach circles", "The main object body will not fade when enabled.")] public Bindable OnlyFadeApproachCircles { get; } = new BindableBool(); @@ -55,6 +56,7 @@ static void applyFadeInAdjustment(OsuHitObject osuObject) public void Update(Playfield playfield) { + return; foreach (var drawableHitObject in playfield.HitObjectContainer.AliveObjects) { var target = (drawableHitObject switch @@ -77,7 +79,7 @@ public void Update(Playfield playfield) continue; } - var fadeTarget = fadeDurationFactor;/*= fadeDurationFactor < 0.2 + var fadeTarget = fadeDurationFactor; /*= fadeDurationFactor < 0.2 ? 0 : Interpolation.ValueAt((float)target.Time.Current, 1f, 0f, fadeOutStartTime, fadeOutStartTime + fadeOutDuration, Easing.InQuart);*/ var fadeInTarget = Interpolation.ValueAt((float)target.Time.Current, 0f, 1f, fadeOutStartTime, fadeInEndTime); @@ -100,6 +102,12 @@ protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, applyHiddenState(hitObject, false); } + protected override uint GetHiddenComboInfluence(JudgementResult judgementResult) => judgementResult.HitObject switch + { + HitCircle and not SliderEndCircle => 1, + _ => 0, + }; + private void applyHiddenState(DrawableHitObject drawableObject, bool increaseVisibility) { if (!(drawableObject is DrawableOsuHitObject drawableOsuObject)) @@ -109,13 +117,14 @@ private void applyHiddenState(DrawableHitObject drawableObject, bool increaseVis (double fadeStartTime, double fadeDuration) = getFadeOutParameters(drawableOsuObject); + increaseVisibility = increaseVisibility || OverrideShowHitObjects(); // process approach circle hiding first (to allow for early return below). if (!increaseVisibility) { if (drawableObject is DrawableHitCircle circle) { using (circle.BeginAbsoluteSequence(hitObject.StartTime - hitObject.TimePreempt)) - circle.ApproachCircle.FadeOut(); + circle.ApproachCircle.FadeTo(_alpha); } else if (drawableObject is DrawableSpinner spinner) { @@ -149,25 +158,25 @@ private void applyHiddenState(DrawableHitObject drawableObject, bool increaseVis case DrawableHitCircle circle: Drawable fadeTarget = circle; - if (increaseVisibility || true) + if (increaseVisibility || true) // TODO clean this up { // only fade the circle piece (not the approach circle) for the increased visibility object. fadeTarget = circle.CirclePiece; } using (drawableObject.BeginAbsoluteSequence(fadeStartTime)) - fadeTarget.FadeTo(alpha, fadeDuration); + fadeTarget.FadeTo(_alpha * 0.5f, fadeDuration); break; case DrawableSlider slider: using (slider.BeginAbsoluteSequence(fadeStartTime)) - slider.Body.FadeTo(alpha, fadeDuration, Easing.Out); + slider.Body.FadeTo(_alpha * 0.5f, fadeDuration, Easing.Out); break; case DrawableSliderTick sliderTick: using (sliderTick.BeginAbsoluteSequence(fadeStartTime)) - sliderTick.FadeTo(alpha, fadeDuration); + sliderTick.FadeTo(_alpha * 0.5f, fadeDuration); break; @@ -236,27 +245,30 @@ private static void hideSpinnerApproachCircle(DrawableSpinner spinner) approachCircle.Hide(); } - private float alpha = 0; + private float _alpha => OverrideShowHitObjects() ? 1 : 0; private float fadeDurationFactor = 0.9f; + private int combo = 0; - public void ApplyToHealthProcessor(HealthProcessor healthProcessor) + /* + public override void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - return; - healthProcessor.Health.ValueChanged += newHealth => + scoreProcessor.NewJudgement += result => { - fadeDurationFactor = Math.Clamp(Interpolation.ValueAt((float)newHealth.NewValue, 1.2f, -0.1f, 0.2f, 0.8f), 0f, 1f); + if (result.HitObject is HitCircle and not SliderEndCircle) + combo++; }; - } - public override void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) - { + scoreProcessor.JudgementReverted += result => + { + if (result.HitObject is HitCircle and not SliderEndCircle) + combo--; + }; scoreProcessor.Combo.ValueChanged += combo => { fadeDurationFactor = combo.NewValue == 0f ? 1f : 1f - (float)combo.NewValue / 25f; fadeDurationFactor = Math.Clamp(fadeDurationFactor, 0f, 1f); }; } - - + */ } } diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 2915cb9bea27..4ac3c46707c2 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -1,10 +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 NUnit.Framework.Internal; +using OpenTabletDriver.Plugin; +using osu.Framework.Bindables; using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using Logger = osu.Framework.Logging.Logger; +using LogLevel = osu.Framework.Logging.LogLevel; namespace osu.Game.Rulesets.Mods { @@ -16,9 +26,17 @@ public abstract class ModHidden : ModWithVisibilityAdjustment, IApplicableToScor public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => UsesDefaultConfiguration; - public virtual void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + private bool lastShown; + private uint _combo; + private bool Show => _combo < EnableAtCombo.Value; + + [SettingSource("Enable at combo", "The combo at which the hidden effect will start to take effect.")] + public BindableNumber EnableAtCombo { get; } = new BindableNumber(10) { - } + MinValue = 0, + MaxValue = 100, + Precision = 1, + }; public virtual ScoreRank AdjustRank(ScoreRank rank, double accuracy) { @@ -34,5 +52,26 @@ public virtual ScoreRank AdjustRank(ScoreRank rank, double accuracy) return rank; } } + + public virtual void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + _combo = (uint)EnableAtCombo.Value; + lastShown = false; + + scoreProcessor.NewJudgement += result => ScoreProcessorOnNewJudgement(result); + scoreProcessor.JudgementReverted += result => ScoreProcessorOnNewJudgement(result, true); + + void ScoreProcessorOnNewJudgement(JudgementResult obj, bool revert = false) + { + if (revert) return; + uint abs = GetHiddenComboInfluence(obj); + _combo = !obj.IsHit && abs > 0 ? 0 : _combo + abs; + Logger.Log($"Combo: {_combo}", level: LogLevel.Verbose); + } + } + + protected virtual bool OverrideShowHitObjects() => Show; + + protected virtual uint GetHiddenComboInfluence(JudgementResult judgementResult) => 0; } } diff --git a/osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs b/osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs index 2e3619ec6373..b423ead7b167 100644 --- a/osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs +++ b/osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs @@ -5,6 +5,7 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -78,13 +79,15 @@ public virtual void ApplyToDrawableHitObject(DrawableHitObject dho) dho.ApplyCustomUpdateState += (o, state) => { // Increased visibility is applied to the entire first object, including all of its nested hitobjects. - if (IncreaseFirstObjectVisibility.Value && isObjectEqualToOrNestedIn(o.HitObject, FirstObject)) + // TODO Not sure if this OverrideShowHitObject() is necessary, seems not beacause of pooling + if ((IncreaseFirstObjectVisibility.Value && isObjectEqualToOrNestedIn(o.HitObject, FirstObject))) ApplyIncreasedVisibilityState(o, state); else ApplyNormalVisibilityState(o, state); }; } + /// /// Checks whether a given object is nested within a target. ///