From b75437ee1303dfef70cd548b15a9fcc20eea8032 Mon Sep 17 00:00:00 2001 From: Darius Wattimena Date: Tue, 15 Oct 2024 21:13:04 +0200 Subject: [PATCH 1/4] Fix an issue where changing the CircleSize wouldn't adjust the catcher size and represent hyperdashes incorrectly --- .../Edit/CatchEditorPlayfield.cs | 6 ++++- .../Edit/DrawableCatchEditorRuleset.cs | 23 +++++++++++++++++++ osu.Game.Rulesets.Catch/UI/Catcher.cs | 18 +++++++++++---- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs index c9481c2757..78f5c3e9ed 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Catch.Edit { public partial class CatchEditorPlayfield : CatchPlayfield { - // TODO fixme: the size of the catcher is not changed when circle size is changed in setup screen. public CatchEditorPlayfield(IBeatmapDifficultyInfo difficulty) : base(difficulty) { @@ -23,5 +22,10 @@ namespace osu.Game.Rulesets.Catch.Edit // TODO: disable hit lighting as well } + + public void ApplyCircleSizeToCatcher(IBeatmapDifficultyInfo difficulty) + { + Catcher.SetScaleAndCatchWidth(difficulty); + } } } diff --git a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs index 7ad2106ab9..cd6d490a7f 100644 --- a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs +++ b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs @@ -2,16 +2,22 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Catch.Edit { public partial class DrawableCatchEditorRuleset : DrawableCatchRuleset { + [Resolved] + private EditorBeatmap editorBeatmap { get; set; } = null!; + public readonly BindableDouble TimeRangeMultiplier = new BindableDouble(1); public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) @@ -28,6 +34,23 @@ namespace osu.Game.Rulesets.Catch.Edit TimeRange.Value = gamePlayTimeRange * TimeRangeMultiplier.Value * playfieldStretch; } + protected override void LoadComplete() + { + base.LoadComplete(); + + editorBeatmap.BeatmapReprocessed += onBeatmapReprocessed; + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (editorBeatmap.IsNotNull()) + editorBeatmap.BeatmapReprocessed -= onBeatmapReprocessed; + } + + private void onBeatmapReprocessed() => (Playfield as CatchEditorPlayfield)?.ApplyCircleSizeToCatcher(editorBeatmap.Difficulty); + protected override Playfield CreatePlayfield() => new CatchEditorPlayfield(Beatmap.Difficulty); public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new CatchEditorPlayfieldAdjustmentContainer(); diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 6a1b251d60..3a0863473a 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// Width of the area that can be used to attempt catches during gameplay. /// - public readonly float CatchWidth; + public float CatchWidth; private readonly SkinnableCatcher body; @@ -142,10 +142,7 @@ namespace osu.Game.Rulesets.Catch.UI Size = new Vector2(BASE_SIZE); - if (difficulty != null) - Scale = calculateScale(difficulty); - - CatchWidth = CalculateCatchWidth(Scale); + SetScaleAndCatchWidth(difficulty); InternalChildren = new Drawable[] { @@ -312,6 +309,17 @@ namespace osu.Game.Rulesets.Catch.UI } } + /// + /// Set the scale and catch width. + /// + public void SetScaleAndCatchWidth(IBeatmapDifficultyInfo? difficulty) + { + if (difficulty != null) + Scale = calculateScale(difficulty); + + CatchWidth = CalculateCatchWidth(Scale); + } + /// /// Drop any fruit off the plate. /// From 5e642cbce72862b29b117829e7ec90d6d6b0ce1e Mon Sep 17 00:00:00 2001 From: Darius Wattimena Date: Thu, 24 Oct 2024 23:17:47 +0200 Subject: [PATCH 2/4] Apply code feedback and also resize catcher trails when any is shown --- .../Edit/CatchEditorPlayfield.cs | 5 ----- .../Edit/DrawableCatchEditorRuleset.cs | 9 ++++++++- osu.Game.Rulesets.Catch/UI/Catcher.cs | 6 +++--- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 8 ++++---- .../UI/CatcherTrailDisplay.cs | 20 +++++++++++++++++++ 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs index 78f5c3e9ed..3967c54f4b 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs @@ -22,10 +22,5 @@ namespace osu.Game.Rulesets.Catch.Edit // TODO: disable hit lighting as well } - - public void ApplyCircleSizeToCatcher(IBeatmapDifficultyInfo difficulty) - { - Catcher.SetScaleAndCatchWidth(difficulty); - } } } diff --git a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs index cd6d490a7f..86cdc2df5c 100644 --- a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs +++ b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs @@ -49,7 +49,14 @@ namespace osu.Game.Rulesets.Catch.Edit editorBeatmap.BeatmapReprocessed -= onBeatmapReprocessed; } - private void onBeatmapReprocessed() => (Playfield as CatchEditorPlayfield)?.ApplyCircleSizeToCatcher(editorBeatmap.Difficulty); + private void onBeatmapReprocessed() + { + if (Playfield is CatchEditorPlayfield catchPlayfield) + { + catchPlayfield.Catcher.ApplyDifficulty(editorBeatmap.Difficulty); + catchPlayfield.CatcherArea.CatcherTrails.UpdateCatcherTrailsScale(catchPlayfield.Catcher.BodyScale); + } + } protected override Playfield CreatePlayfield() => new CatchEditorPlayfield(Beatmap.Difficulty); diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 3a0863473a..ebf3e47fd7 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// Width of the area that can be used to attempt catches during gameplay. /// - public float CatchWidth; + public float CatchWidth { get; private set; } private readonly SkinnableCatcher body; @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Catch.UI Size = new Vector2(BASE_SIZE); - SetScaleAndCatchWidth(difficulty); + ApplyDifficulty(difficulty); InternalChildren = new Drawable[] { @@ -312,7 +312,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// Set the scale and catch width. /// - public void SetScaleAndCatchWidth(IBeatmapDifficultyInfo? difficulty) + public void ApplyDifficulty(IBeatmapDifficultyInfo? difficulty) { if (difficulty != null) Scale = calculateScale(difficulty); diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 338e1364a9..7f0a79ef49 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatchComboDisplay comboDisplay; - private readonly CatcherTrailDisplay catcherTrails; + public readonly CatcherTrailDisplay CatcherTrails; private Catcher catcher = null!; @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI Children = new Drawable[] { catcherContainer = new Container { RelativeSizeAxes = Axes.Both }, - catcherTrails = new CatcherTrailDisplay(), + CatcherTrails = new CatcherTrailDisplay(), comboDisplay = new CatchComboDisplay { RelativeSizeAxes = Axes.None, @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Catch.UI { const double trail_generation_interval = 16; - if (Time.Current - catcherTrails.LastDashTrailTime >= trail_generation_interval) + if (Time.Current - CatcherTrails.LastDashTrailTime >= trail_generation_interval) displayCatcherTrail(Catcher.HyperDashing ? CatcherTrailAnimation.HyperDashing : CatcherTrailAnimation.Dashing); } @@ -170,6 +170,6 @@ namespace osu.Game.Rulesets.Catch.UI } } - private void displayCatcherTrail(CatcherTrailAnimation animation) => catcherTrails.Add(new CatcherTrailEntry(Time.Current, Catcher.CurrentState, Catcher.X, Catcher.BodyScale, animation)); + private void displayCatcherTrail(CatcherTrailAnimation animation) => CatcherTrails.Add(new CatcherTrailEntry(Time.Current, Catcher.CurrentState, Catcher.X, Catcher.BodyScale, animation)); } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index e3e01c1b39..6a9162da91 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Catch.Skinning; using osu.Game.Rulesets.Objects.Pooling; using osu.Game.Skinning; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI @@ -55,6 +56,25 @@ namespace osu.Game.Rulesets.Catch.UI }; } + /// + /// Update the scale of all trails. + /// + /// The new body scale of the Catcher + public void UpdateCatcherTrailsScale(Vector2 scale) + { + applyScaleChange(scale, dashTrails); + applyScaleChange(scale, hyperDashTrails); + applyScaleChange(scale, hyperDashAfterImages); + } + + private void applyScaleChange(Vector2 scale, Container trails) + { + foreach (var trail in trails) + { + trail.Scale = scale; + } + } + protected override void LoadComplete() { base.LoadComplete(); From 2b14d78f04083afb3f8e067ce00554fdfdc5e41f Mon Sep 17 00:00:00 2001 From: Darius Wattimena Date: Thu, 24 Oct 2024 23:40:23 +0200 Subject: [PATCH 3/4] Hide the after image instead as the effect can't be resized easily --- osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index 6a9162da91..ad2ae53f48 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -64,7 +64,12 @@ namespace osu.Game.Rulesets.Catch.UI { applyScaleChange(scale, dashTrails); applyScaleChange(scale, hyperDashTrails); - applyScaleChange(scale, hyperDashAfterImages); + + foreach (var afterImage in hyperDashAfterImages) + { + afterImage.Hide(); + afterImage.Expire(); + } } private void applyScaleChange(Vector2 scale, Container trails) From 488fabcd5479ac4cdd43889ed71202eb00b75278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 1 Nov 2024 13:07:32 +0100 Subject: [PATCH 4/4] Use alternative method of resizing the catcher trails This one preserves the catcher afterimage, which I'd count as a win. --- .../UI/CatcherTrailDisplay.cs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index ad2ae53f48..6b888be961 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; @@ -62,21 +63,16 @@ namespace osu.Game.Rulesets.Catch.UI /// The new body scale of the Catcher public void UpdateCatcherTrailsScale(Vector2 scale) { - applyScaleChange(scale, dashTrails); - applyScaleChange(scale, hyperDashTrails); + var oldEntries = Entries.ToList(); - foreach (var afterImage in hyperDashAfterImages) - { - afterImage.Hide(); - afterImage.Expire(); - } - } + Clear(); - private void applyScaleChange(Vector2 scale, Container trails) - { - foreach (var trail in trails) + foreach (var oldEntry in oldEntries) { - trail.Scale = scale; + // use magnitude of the new scale while preserving the sign of the old one in the X direction. + // the end effect is preserving the direction in which the trail sprites face, which is important. + var targetScale = new Vector2(Math.Abs(scale.X) * Math.Sign(oldEntry.Scale.X), Math.Abs(scale.Y)); + Add(new CatcherTrailEntry(oldEntry.LifetimeStart, oldEntry.CatcherState, oldEntry.Position, targetScale, oldEntry.Animation)); } }