1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-31 17:12:56 +08:00

revert mod visibility toggle

This commit is contained in:
Sheepposu 2024-02-21 23:23:40 -05:00
parent 1d552e7c90
commit 35b89966bc
4 changed files with 17 additions and 142 deletions

View File

@ -2,11 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Bindables;
using osu.Framework.Localisation;
using osu.Game.Configuration;
@ -14,14 +12,13 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Skinning;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModHidden : ModHidden, IHidesApproachCircles, IToggleableVisibility
public class OsuModHidden : ModHidden, IHidesApproachCircles
{
[SettingSource("Only fade approach circles", "The main object body will not fade when enabled.")]
public Bindable<bool> OnlyFadeApproachCircles { get; } = new BindableBool();
@ -31,41 +28,24 @@ namespace osu.Game.Rulesets.Osu.Mods
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth) };
private bool toggledOff = false;
private IBeatmap? appliedBeatmap;
public const double FADE_IN_DURATION_MULTIPLIER = 0.4;
public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;
protected override bool IsFirstAdjustableObject(HitObject hitObject) => !(hitObject is Spinner || hitObject is SpinnerTick);
public override void ApplyToBeatmap(IBeatmap? beatmap = null)
public override void ApplyToBeatmap(IBeatmap beatmap)
{
if (beatmap is not null)
appliedBeatmap = beatmap;
else if (appliedBeatmap is null)
return;
else
beatmap = appliedBeatmap;
base.ApplyToBeatmap(beatmap);
foreach (var obj in beatmap.HitObjects.OfType<OsuHitObject>())
applyFadeInAdjustment(obj);
}
private static void applyFadeInAdjustment(OsuHitObject osuObject)
{
osuObject.TimeFadeIn = osuObject.TimePreempt * FADE_IN_DURATION_MULTIPLIER;
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
applyFadeInAdjustment(nested);
}
private static void revertFadeInAdjustment(OsuHitObject osuObject)
{
osuObject.TimeFadeIn = OsuHitObject.CalculateTimeFadeIn(osuObject.TimePreempt);
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
revertFadeInAdjustment(nested);
static void applyFadeInAdjustment(OsuHitObject osuObject)
{
osuObject.TimeFadeIn = osuObject.TimePreempt * FADE_IN_DURATION_MULTIPLIER;
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
applyFadeInAdjustment(nested);
}
}
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
@ -80,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Mods
private void applyHiddenState(DrawableHitObject drawableObject, bool increaseVisibility)
{
if (!(drawableObject is DrawableOsuHitObject drawableOsuObject) || toggledOff)
if (!(drawableObject is DrawableOsuHitObject drawableOsuObject))
return;
OsuHitObject hitObject = drawableOsuObject.HitObject;
@ -203,11 +183,8 @@ namespace osu.Game.Rulesets.Osu.Mods
}
}
private void hideSpinnerApproachCircle(DrawableSpinner spinner)
private static void hideSpinnerApproachCircle(DrawableSpinner spinner)
{
if (toggledOff)
return;
var approachCircle = (spinner.Body.Drawable as IHasApproachCircle)?.ApproachCircle;
if (approachCircle == null)
return;
@ -215,39 +192,5 @@ namespace osu.Game.Rulesets.Osu.Mods
using (spinner.BeginAbsoluteSequence(spinner.HitObject.StartTime - spinner.HitObject.TimePreempt))
approachCircle.Hide();
}
public void ToggleOffVisibility(Playfield playfield)
{
if (toggledOff)
return;
toggledOff = true;
if (appliedBeatmap is not null)
foreach (var obj in appliedBeatmap.HitObjects.OfType<OsuHitObject>())
revertFadeInAdjustment(obj);
foreach (var dho in playfield.AllHitObjects)
{
dho.RefreshStateTransforms();
}
}
public void ToggleOnVisibility(Playfield playfield)
{
if (!toggledOff)
return;
toggledOff = false;
if (appliedBeatmap is not null)
ApplyToBeatmap();
foreach (var dho in playfield.AllHitObjects)
{
dho.RefreshStateTransforms();
ApplyToDrawableHitObject(dho);
}
}
}
}
}

View File

@ -154,19 +154,17 @@ namespace osu.Game.Rulesets.Osu.Objects
});
}
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
// Note that this doesn't exactly match the AR>10 visuals as they're classically known, but it feels good.
// This adjustment is necessary for AR>10, otherwise TimePreempt can become smaller leading to hitcircles not fully fading in.
static public double CalculateTimeFadeIn(double timePreempt) => 400 * Math.Min(1, timePreempt / PREEMPT_MIN);
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty)
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_MAX, PREEMPT_MID, PREEMPT_MIN);
TimeFadeIn = CalculateTimeFadeIn(TimePreempt);
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
// Note that this doesn't exactly match the AR>10 visuals as they're classically known, but it feels good.
// This adjustment is necessary for AR>10, otherwise TimePreempt can become smaller leading to hitcircles not fully fading in.
TimeFadeIn = 400 * Math.Min(1, TimePreempt / PREEMPT_MIN);
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize, true);
}

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osu.Game.Localisation;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play.PlayerSettings;
@ -23,7 +22,6 @@ namespace osu.Game.Rulesets.Osu.UI
private readonly PlayerCheckbox aimMarkerToggle;
private readonly PlayerCheckbox hideCursorToggle;
private readonly PlayerCheckbox aimLinesToggle;
private readonly FillFlowContainer modTogglesContainer;
public OsuAnalysisSettings(DrawableRuleset drawableRuleset)
: base(drawableRuleset)
@ -33,37 +31,8 @@ namespace osu.Game.Rulesets.Osu.UI
hitMarkerToggle = new PlayerCheckbox { LabelText = PlayerSettingsOverlayStrings.HitMarkers },
aimMarkerToggle = new PlayerCheckbox { LabelText = PlayerSettingsOverlayStrings.AimMarkers },
aimLinesToggle = new PlayerCheckbox { LabelText = PlayerSettingsOverlayStrings.AimLines },
hideCursorToggle = new PlayerCheckbox { LabelText = PlayerSettingsOverlayStrings.HideCursor },
new OsuScrollContainer(Direction.Horizontal)
{
RelativeSizeAxes = Axes.X,
Height = ModSwitchSmall.DEFAULT_SIZE,
ScrollbarOverlapsContent = false,
Child = modTogglesContainer = new FillFlowContainer
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X
}
}
hideCursorToggle = new PlayerCheckbox { LabelText = PlayerSettingsOverlayStrings.HideCursor }
};
foreach (var mod in drawableRuleset.Mods)
{
if (mod is IToggleableVisibility toggleableMod)
{
var modSwitch = new SelectableModSwitchSmall(mod)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Active = { Value = true }
};
modSwitch.Active.BindValueChanged((v) => onModToggle(toggleableMod, v));
modTogglesContainer.Add(modSwitch);
}
}
}
protected override void LoadComplete()
@ -85,29 +54,5 @@ namespace osu.Game.Rulesets.Osu.UI
drawableRuleset.Playfield.Cursor.FadeIn();
}
}
private void onModToggle(IToggleableVisibility mod, ValueChangedEvent<bool> toggled)
{
if (toggled.NewValue)
{
mod.ToggleOnVisibility(drawableRuleset.Playfield);
} else
{
mod.ToggleOffVisibility(drawableRuleset.Playfield);
}
}
private partial class SelectableModSwitchSmall : ModSwitchSmall
{
public SelectableModSwitchSmall(IMod mod)
: base(mod)
{}
protected override bool OnClick(ClickEvent e)
{
Active.Value = !Active.Value;
return true;
}
}
}
}

View File

@ -1,11 +0,0 @@
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mods
{
public interface IToggleableVisibility
{
public void ToggleOffVisibility(Playfield playfield);
public void ToggleOnVisibility(Playfield playfield);
}
}