From 8da502da4405ad5658a702f67e8ad3eb71e24453 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 9 Dec 2020 17:46:36 +0900 Subject: [PATCH 01/12] Separate asymmetric CatchHitObject.X to EffectiveX and OriginalX --- .../Objects/CatchHitObject.cs | 25 +++++++++++-------- .../Drawables/DrawableCatchHitObject.cs | 4 +-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index b86b3a7496..9fdd590464 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -16,23 +16,27 @@ namespace osu.Game.Rulesets.Catch.Objects { public const float OBJECT_RADIUS = 64; - // This value is after XOffset applied. - public readonly Bindable XBindable = new Bindable(); + public readonly Bindable OriginalXBindable = new Bindable(); - // This value is before XOffset applied. - private float originalX; + public float OriginalX + { + get => OriginalXBindable.Value; + set => OriginalXBindable.Value = value; + } /// /// The horizontal position of the fruit between 0 and . /// public float X { - // TODO: I don't like this asymmetry. - get => XBindable.Value; - // originalX is set by `XBindable.BindValueChanged` - set => XBindable.Value = value + xOffset; + get => EffectiveX; + set => OriginalXBindable.Value = value; } + public readonly Bindable EffectiveXBindable = new Bindable(); + + public float EffectiveX => EffectiveXBindable.Value; + private float xOffset; /// @@ -40,11 +44,10 @@ namespace osu.Game.Rulesets.Catch.Objects /// internal float XOffset { - get => xOffset; set { xOffset = value; - XBindable.Value = originalX + xOffset; + EffectiveXBindable.Value = OriginalX + xOffset; } } @@ -116,7 +119,7 @@ namespace osu.Game.Rulesets.Catch.Objects protected CatchHitObject() { - XBindable.BindValueChanged(x => originalX = x.NewValue - xOffset); + OriginalXBindable.BindValueChanged(change => EffectiveXBindable.Value = change.NewValue + xOffset); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index bfd124c691..131edb650f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -38,14 +38,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { base.OnApply(); - XBindable.BindTo(HitObject.XBindable); + XBindable.BindTo(HitObject.EffectiveXBindable); } protected override void OnFree() { base.OnFree(); - XBindable.UnbindFrom(HitObject.XBindable); + XBindable.UnbindFrom(HitObject.EffectiveXBindable); } public Func CheckPosition; From c1f3f1c231c259ff4b494ce3bdcb3d11d3632469 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 9 Dec 2020 17:47:17 +0900 Subject: [PATCH 02/12] Obsolete `X` getter --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 9fdd590464..a5c254f2f1 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,6 +1,7 @@ // 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.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -29,6 +30,7 @@ namespace osu.Game.Rulesets.Catch.Objects /// public float X { + [Obsolete("Use EffectiveX instead")] get => EffectiveX; set => OriginalXBindable.Value = value; } From 96f3e0dad8243d221592d99ed39949488d829e6f Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 9 Dec 2020 17:58:53 +0900 Subject: [PATCH 03/12] Replace CatchHitObject.X usage to EffectiveX and OriginalX --- .../CatchBeatmapConversionTest.cs | 2 +- .../TestSceneCatcherArea.cs | 2 +- .../Beatmaps/CatchBeatmapProcessor.cs | 14 +++++++------- .../Preprocessing/CatchDifficultyHitObject.cs | 4 ++-- .../Objects/Drawables/DrawableCatchHitObject.cs | 2 +- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 8 ++++---- .../Replays/CatchAutoGenerator.cs | 16 ++++++++-------- osu.Game.Rulesets.Catch/UI/Catcher.cs | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 466cbdaf8d..33fdcdaf1e 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Catch.Tests public float Position { - get => HitObject?.X ?? position; + get => HitObject?.EffectiveX ?? position; set => position = value; } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 31c285ef22..5079e57e5e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.Tests private void attemptCatch(Fruit fruit) { - fruit.X += catcher.X; + fruit.OriginalX += catcher.X; fruit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 00ce9ea8c2..fac5d03833 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps case JuiceStream juiceStream: // Todo: BUG!! Stable used the last control point as the final position of the path, but it should use the computed path instead. - lastPosition = juiceStream.X + juiceStream.Path.ControlPoints[^1].Position.Value.X; + lastPosition = juiceStream.OriginalX + juiceStream.Path.ControlPoints[^1].Position.Value.X; // Todo: BUG!! Stable attempted to use the end time of the stream, but referenced it too early in execution and used the start time instead. lastStartTime = juiceStream.StartTime; @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps catchObject.XOffset = 0; if (catchObject is TinyDroplet) - catchObject.XOffset = Math.Clamp(rng.Next(-20, 20), -catchObject.X, CatchPlayfield.WIDTH - catchObject.X); + catchObject.XOffset = Math.Clamp(rng.Next(-20, 20), -catchObject.OriginalX, CatchPlayfield.WIDTH - catchObject.OriginalX); else if (catchObject is Droplet) rng.Next(); // osu!stable retrieved a random droplet rotation } @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) { - float offsetPosition = hitObject.X; + float offsetPosition = hitObject.OriginalX; double startTime = hitObject.StartTime; if (lastPosition == null) @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (positionDiff == 0) { applyRandomOffset(ref offsetPosition, timeDiff / 4d, rng); - hitObject.XOffset = offsetPosition - hitObject.X; + hitObject.XOffset = offsetPosition - hitObject.OriginalX; return; } @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (Math.Abs(positionDiff) < timeDiff / 3) applyOffset(ref offsetPosition, positionDiff); - hitObject.XOffset = offsetPosition - hitObject.X; + hitObject.XOffset = offsetPosition - hitObject.OriginalX; lastPosition = offsetPosition; lastStartTime = startTime; @@ -230,9 +230,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps currentObject.HyperDashTarget = null; currentObject.DistanceToHyperDash = 0; - int thisDirection = nextObject.X > currentObject.X ? 1 : -1; + int thisDirection = nextObject.EffectiveX > currentObject.EffectiveX ? 1 : -1; double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable - double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth); + double distanceToNext = Math.Abs(nextObject.EffectiveX - currentObject.EffectiveX) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth); float distanceToHyper = (float)(timeToNext * Catcher.BASE_SPEED - distanceToNext); if (distanceToHyper < 0) diff --git a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs index dcd410e08f..d936ef97ac 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs @@ -32,8 +32,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. var scalingFactor = normalized_hitobject_radius / halfCatcherWidth; - NormalizedPosition = BaseObject.X * scalingFactor; - LastNormalizedPosition = LastObject.X * scalingFactor; + NormalizedPosition = BaseObject.EffectiveX * scalingFactor; + LastNormalizedPosition = LastObject.EffectiveX * scalingFactor; // Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure StrainTime = Math.Max(40, DeltaTime); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 131edb650f..c511ea5006 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables protected override double InitialLifetimeOffset => HitObject.TimePreempt; - protected override float SamplePlaybackPosition => HitObject.X / CatchPlayfield.WIDTH; + protected override float SamplePlaybackPosition => HitObject.EffectiveX / CatchPlayfield.WIDTH; public int RandomSeed => HitObject?.RandomSeed ?? 0; diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index d5819935ad..35fd58826e 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new TinyDroplet { StartTime = t + lastEvent.Value.Time, - X = X + Path.PositionAt( + X = OriginalX + Path.PositionAt( lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X, }); } @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = dropletSamples, StartTime = e.Time, - X = X + Path.PositionAt(e.PathProgress).X, + X = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; @@ -104,14 +104,14 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = this.GetNodeSamples(nodeIndex++), StartTime = e.Time, - X = X + Path.PositionAt(e.PathProgress).X, + X = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; } } } - public float EndX => X + this.CurvePositionAt(1).X; + public float EndX => OriginalX + this.CurvePositionAt(1).X; public double Duration { diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index dfc81ee8d9..32e8ab5da7 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Replays void moveToNext(PalpableCatchHitObject h) { - float positionChange = Math.Abs(lastPosition - h.X); + float positionChange = Math.Abs(lastPosition - h.EffectiveX); double timeAvailable = h.StartTime - lastTime; // So we can either make it there without a dash or not. @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Replays // todo: get correct catcher size, based on difficulty CS. const float catcher_width_half = CatcherArea.CATCHER_SIZE * 0.3f * 0.5f; - if (lastPosition - catcher_width_half < h.X && lastPosition + catcher_width_half > h.X) + if (lastPosition - catcher_width_half < h.EffectiveX && lastPosition + catcher_width_half > h.EffectiveX) { // we are already in the correct range. lastTime = h.StartTime; @@ -66,12 +66,12 @@ namespace osu.Game.Rulesets.Catch.Replays if (impossibleJump) { - addFrame(h.StartTime, h.X); + addFrame(h.StartTime, h.EffectiveX); } else if (h.HyperDash) { addFrame(h.StartTime - timeAvailable, lastPosition); - addFrame(h.StartTime, h.X); + addFrame(h.StartTime, h.EffectiveX); } else if (dashRequired) { @@ -80,23 +80,23 @@ namespace osu.Game.Rulesets.Catch.Replays double timeWeNeedToSave = timeAtNormalSpeed - timeAvailable; double timeAtDashSpeed = timeWeNeedToSave / 2; - float midPosition = (float)Interpolation.Lerp(lastPosition, h.X, (float)timeAtDashSpeed / timeAvailable); + float midPosition = (float)Interpolation.Lerp(lastPosition, h.EffectiveX, (float)timeAtDashSpeed / timeAvailable); // dash movement addFrame(h.StartTime - timeAvailable + 1, lastPosition, true); addFrame(h.StartTime - timeAvailable + timeAtDashSpeed, midPosition); - addFrame(h.StartTime, h.X); + addFrame(h.StartTime, h.EffectiveX); } else { double timeBefore = positionChange / movement_speed; addFrame(h.StartTime - timeBefore, lastPosition); - addFrame(h.StartTime, h.X); + addFrame(h.StartTime, h.EffectiveX); } lastTime = h.StartTime; - lastPosition = h.X; + lastPosition = h.EffectiveX; } foreach (var obj in Beatmap.HitObjects) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index f164c2655a..ed875e7002 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Catch.UI var halfCatchWidth = catchWidth * 0.5f; // this stuff wil disappear once we move fruit to non-relative coordinate space in the future. - var catchObjectPosition = fruit.X; + var catchObjectPosition = fruit.EffectiveX; var catcherPosition = Position.X; return catchObjectPosition >= catcherPosition - halfCatchWidth && @@ -250,10 +250,10 @@ namespace osu.Game.Rulesets.Catch.UI { var target = hitObject.HyperDashTarget; var timeDifference = target.StartTime - hitObject.StartTime; - double positionDifference = target.X - X; + double positionDifference = target.EffectiveX - X; var velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); - SetHyperDashState(Math.Abs(velocity), target.X); + SetHyperDashState(Math.Abs(velocity), target.EffectiveX); } else SetHyperDashState(); From cd2db59900f8d8b7f79dea26bb9a035fb334f503 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 11:05:26 +0900 Subject: [PATCH 04/12] XBindable -> EffectiveXBindable in catch DHO --- .../Objects/Drawables/DrawableCatchHitObject.cs | 6 +++--- .../Objects/Drawables/DrawablePalpableCatchHitObject.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index c511ea5006..edd607a443 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { public abstract class DrawableCatchHitObject : DrawableHitObject { - public readonly Bindable XBindable = new Bindable(); + public readonly Bindable EffectiveXBindable = new Bindable(); protected override double InitialLifetimeOffset => HitObject.TimePreempt; @@ -38,14 +38,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { base.OnApply(); - XBindable.BindTo(HitObject.EffectiveXBindable); + EffectiveXBindable.BindTo(HitObject.EffectiveXBindable); } protected override void OnFree() { base.OnFree(); - XBindable.UnbindFrom(HitObject.EffectiveXBindable); + EffectiveXBindable.UnbindFrom(HitObject.EffectiveXBindable); } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index 7df06bd92d..d3fa43c6b6 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [BackgroundDependencyLoader] private void load() { - XBindable.BindValueChanged(x => + EffectiveXBindable.BindValueChanged(x => { X = x.NewValue; }, true); From 089f3bebf57f3be57c8a1b2e525681a62f8d095a Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 11:15:49 +0900 Subject: [PATCH 05/12] Add doc comments to catch hit object X properties --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index a5c254f2f1..d40821c840 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -19,6 +19,12 @@ namespace osu.Game.Rulesets.Catch.Objects public readonly Bindable OriginalXBindable = new Bindable(); + /// + /// The horizontal position of the hit object between 0 and . + /// + /// + /// This value is the original value specified in the beatmap, not affected by beatmap processing. + /// public float OriginalX { get => OriginalXBindable.Value; @@ -37,12 +43,15 @@ namespace osu.Game.Rulesets.Catch.Objects public readonly Bindable EffectiveXBindable = new Bindable(); + /// + /// The effective horizontal position of the hit object between 0 and . + /// public float EffectiveX => EffectiveXBindable.Value; private float xOffset; /// - /// A random offset applied to , set by the . + /// A random offset applied to the horizontal value, set by the . /// internal float XOffset { From 36529bdd1b103ea5c5284b70e1cfbf30eec19f2b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 11:25:09 +0900 Subject: [PATCH 06/12] Use OriginalX for CatchHitObject.X instead of EffectiveX And explicitly implement IHasXPosition interface to prevent use of the X property. It should be preferred for beatmap conversion purpose. --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index d40821c840..6a040efb91 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,7 +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 osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -31,14 +30,11 @@ namespace osu.Game.Rulesets.Catch.Objects set => OriginalXBindable.Value = value; } - /// - /// The horizontal position of the fruit between 0 and . - /// + float IHasXPosition.X => OriginalX; + public float X { - [Obsolete("Use EffectiveX instead")] - get => EffectiveX; - set => OriginalXBindable.Value = value; + set => OriginalX = value; } public readonly Bindable EffectiveXBindable = new Bindable(); From f621d977fc413835f411e1dc8cc57d61505ca71e Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 11:32:34 +0900 Subject: [PATCH 07/12] Add some more doc comment --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 6a040efb91..e689d6a178 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects /// /// /// This value is the original value specified in the beatmap, not affected by beatmap processing. + /// It should be used instead of when working on a beatmap, not a gameplay. /// public float OriginalX { @@ -32,6 +33,9 @@ namespace osu.Game.Rulesets.Catch.Objects float IHasXPosition.X => OriginalX; + /// + /// An alias of setter. + /// public float X { set => OriginalX = value; From 7cbbd74df247626ae917f766bcc6f03cd5e37a27 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 11:38:07 +0900 Subject: [PATCH 08/12] Remove X setter from CatchHitObject --- .../Mods/TestSceneCatchModRelax.cs | 8 +++---- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneCatchModHidden.cs | 2 +- .../TestSceneCatchStacker.cs | 2 +- .../TestSceneCatcher.cs | 22 +++++++++---------- .../TestSceneCatcherArea.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 6 ++--- .../TestSceneHyperDash.cs | 14 ++++++------ .../TestSceneJuiceStream.cs | 4 ++-- .../Beatmaps/CatchBeatmapConverter.cs | 4 ++-- .../Objects/CatchHitObject.cs | 8 ------- .../Objects/JuiceStream.cs | 6 ++--- 12 files changed, 36 insertions(+), 44 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index c01aff0aa0..da4834aa73 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -32,22 +32,22 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { new Fruit { - X = CatchPlayfield.CENTER_X, + OriginalX = CatchPlayfield.CENTER_X, StartTime = 0 }, new Fruit { - X = 0, + OriginalX = 0, StartTime = 1000 }, new Fruit { - X = CatchPlayfield.WIDTH, + OriginalX = CatchPlayfield.WIDTH, StartTime = 2000 }, new JuiceStream { - X = CatchPlayfield.CENTER_X, + OriginalX = CatchPlayfield.CENTER_X, StartTime = 3000, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }) } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index f552c3c27b..45cf5095f6 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Tests beatmap.HitObjects.Add(new JuiceStream { - X = CatchPlayfield.CENTER_X - width / 2, + OriginalX = CatchPlayfield.CENTER_X - width / 2, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs index f15da29993..6af9c88088 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Tests { StartTime = 1000, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(0, -192) }), - X = CatchPlayfield.WIDTH / 2 + OriginalX = CatchPlayfield.WIDTH / 2 } } }, diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs index 1ff31697b8..d7835bd8c4 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests { beatmap.HitObjects.Add(new Fruit { - X = (0.5f + i / 2048f * (i % 10 - 5)) * CatchPlayfield.WIDTH, + OriginalX = (0.5f + i / 2048f * (i % 10 - 5)) * CatchPlayfield.WIDTH, StartTime = i * 100, NewCombo = i % 8 == 0 }); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index e8bb57cdf3..d57e8e027e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Catch.Tests JudgementResult result2 = null; AddStep("catch hyper fruit", () => { - attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }, out drawableObject1, out result1); + attemptCatch(new Fruit { HyperDashTarget = new Fruit { OriginalX = 100 } }, out drawableObject1, out result1); }); AddStep("catch normal fruit", () => { @@ -107,14 +107,14 @@ namespace osu.Game.Rulesets.Catch.Tests var halfWidth = Catcher.CalculateCatchWidth(new BeatmapDifficulty { CircleSize = 0 }) / 2; AddStep("catch fruit", () => { - attemptCatch(new Fruit { X = -halfWidth + 1 }); - attemptCatch(new Fruit { X = halfWidth - 1 }); + attemptCatch(new Fruit { OriginalX = -halfWidth + 1 }); + attemptCatch(new Fruit { OriginalX = halfWidth - 1 }); }); checkPlate(2); AddStep("miss fruit", () => { - attemptCatch(new Fruit { X = -halfWidth - 1 }); - attemptCatch(new Fruit { X = halfWidth + 1 }); + attemptCatch(new Fruit { OriginalX = -halfWidth - 1 }); + attemptCatch(new Fruit { OriginalX = halfWidth + 1 }); }); checkPlate(2); } @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Catch.Tests [Test] public void TestFruitChangesCatcherState() { - AddStep("miss fruit", () => attemptCatch(new Fruit { X = 100 })); + AddStep("miss fruit", () => attemptCatch(new Fruit { OriginalX = 100 })); checkState(CatcherAnimationState.Fail); AddStep("catch fruit", () => attemptCatch(new Fruit())); checkState(CatcherAnimationState.Idle); @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper fruit", () => attemptCatch(new Fruit { - HyperDashTarget = new Fruit { X = 100 } + HyperDashTarget = new Fruit { OriginalX = 100 } })); checkHyperDash(true); AddStep("catch normal fruit", () => attemptCatch(new Fruit())); @@ -147,10 +147,10 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit { - HyperDashTarget = new Fruit { X = 100 } + HyperDashTarget = new Fruit { OriginalX = 100 } })); AddStep("catch tiny droplet", () => attemptCatch(new TinyDroplet())); - AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { X = 100 })); + AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { OriginalX = 100 })); // catcher state and hyper dash state is preserved checkState(CatcherAnimationState.Kiai); checkHyperDash(true); @@ -161,9 +161,9 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit { - HyperDashTarget = new Fruit { X = 100 } + HyperDashTarget = new Fruit { OriginalX = 100 } })); - AddStep("miss banana", () => attemptCatch(new Banana { X = 100 })); + AddStep("miss banana", () => attemptCatch(new Banana { OriginalX = 100 })); // catcher state is preserved but hyper dash state is reset checkState(CatcherAnimationState.Kiai); checkHyperDash(false); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 5079e57e5e..423c3b7a13 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Tests AddStep("catch fruit", () => attemptCatch(new Fruit())); AddStep("catch fruit last in combo", () => attemptCatch(new Fruit { LastInCombo = true })); AddStep("catch kiai fruit", () => attemptCatch(new TestSceneCatcher.TestKiaiFruit())); - AddStep("miss last in combo", () => attemptCatch(new Fruit { X = 100, LastInCombo = true })); + AddStep("miss last in combo", () => attemptCatch(new Fruit { OriginalX = 100, LastInCombo = true })); } private void attemptCatch(Fruit fruit) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 3e4995482d..2db534e8c9 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Tests { var fruit = new Fruit { - X = getXCoords(hit), + OriginalX = getXCoords(hit), LastInCombo = i % 4 == 0, StartTime = playfieldTime + 800 + (200 * i) }; @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Catch.Tests var juice = new JuiceStream { - X = xCoords, + OriginalX = xCoords, StartTime = playfieldTime + 1000, Path = new SliderPath(PathType.Linear, new[] { @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Catch.Tests { var banana = new Banana { - X = getXCoords(hit), + OriginalX = getXCoords(hit), LastInCombo = i % 4 == 0, StartTime = playfieldTime + 800 + (200 * i) }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index db09b2bc6b..67af3c4420 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -70,20 +70,20 @@ namespace osu.Game.Rulesets.Catch.Tests beatmap.ControlPointInfo.Add(0, new TimingControlPoint()); // Should produce a hyper-dash (edge case test) - beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); - beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 1816, OriginalX = 56, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 2008, OriginalX = 308, NewCombo = true }); double startTime = 3000; const float left_x = 0.02f * CatchPlayfield.WIDTH; const float right_x = 0.98f * CatchPlayfield.WIDTH; - createObjects(() => new Fruit { X = left_x }); + createObjects(() => new Fruit { OriginalX = left_x }); createObjects(() => new TestJuiceStream(right_x), 1); createObjects(() => new TestJuiceStream(left_x), 1); - createObjects(() => new Fruit { X = right_x }); - createObjects(() => new Fruit { X = left_x }); - createObjects(() => new Fruit { X = right_x }); + createObjects(() => new Fruit { OriginalX = right_x }); + createObjects(() => new Fruit { OriginalX = left_x }); + createObjects(() => new Fruit { OriginalX = right_x }); createObjects(() => new TestJuiceStream(left_x), 1); beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.Tests { public TestJuiceStream(float x) { - X = x; + OriginalX = x; Path = new SliderPath(new[] { diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index 269e783899..dbcf382d62 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Tests { new JuiceStream { - X = CatchPlayfield.CENTER_X, + OriginalX = CatchPlayfield.CENTER_X, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Tests }, new Banana { - X = CatchPlayfield.CENTER_X, + OriginalX = CatchPlayfield.CENTER_X, StartTime = 1000, NewCombo = true } diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 34964fc4ae..55e86a7be2 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps Path = curveData.Path, NodeSamples = curveData.NodeSamples, RepeatCount = curveData.RepeatCount, - X = positionData?.X ?? 0, + OriginalX = positionData?.X ?? 0, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0 @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps Samples = obj.Samples, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, - X = positionData?.X ?? 0 + OriginalX = positionData?.X ?? 0 }.Yield(); } } diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e689d6a178..ebbbd44960 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -33,14 +33,6 @@ namespace osu.Game.Rulesets.Catch.Objects float IHasXPosition.X => OriginalX; - /// - /// An alias of setter. - /// - public float X - { - set => OriginalX = value; - } - public readonly Bindable EffectiveXBindable = new Bindable(); /// diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 35fd58826e..bda0457c83 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new TinyDroplet { StartTime = t + lastEvent.Value.Time, - X = OriginalX + Path.PositionAt( + OriginalX = OriginalX + Path.PositionAt( lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X, }); } @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = dropletSamples, StartTime = e.Time, - X = OriginalX + Path.PositionAt(e.PathProgress).X, + OriginalX = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = this.GetNodeSamples(nodeIndex++), StartTime = e.Time, - X = OriginalX + Path.PositionAt(e.PathProgress).X, + OriginalX = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; } From d96399ea42130f3727d0188aa1ec8a0855c0b4b7 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 13:18:14 +0900 Subject: [PATCH 09/12] Revert "Remove X setter from CatchHitObject" This reverts commit 7cbbd74d --- .../Mods/TestSceneCatchModRelax.cs | 8 +++---- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneCatchModHidden.cs | 2 +- .../TestSceneCatchStacker.cs | 2 +- .../TestSceneCatcher.cs | 22 +++++++++---------- .../TestSceneCatcherArea.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 6 ++--- .../TestSceneHyperDash.cs | 14 ++++++------ .../TestSceneJuiceStream.cs | 4 ++-- .../Beatmaps/CatchBeatmapConverter.cs | 4 ++-- .../Objects/CatchHitObject.cs | 8 +++++++ .../Objects/JuiceStream.cs | 6 ++--- 12 files changed, 44 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index da4834aa73..c01aff0aa0 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -32,22 +32,22 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { new Fruit { - OriginalX = CatchPlayfield.CENTER_X, + X = CatchPlayfield.CENTER_X, StartTime = 0 }, new Fruit { - OriginalX = 0, + X = 0, StartTime = 1000 }, new Fruit { - OriginalX = CatchPlayfield.WIDTH, + X = CatchPlayfield.WIDTH, StartTime = 2000 }, new JuiceStream { - OriginalX = CatchPlayfield.CENTER_X, + X = CatchPlayfield.CENTER_X, StartTime = 3000, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }) } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 45cf5095f6..f552c3c27b 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Tests beatmap.HitObjects.Add(new JuiceStream { - OriginalX = CatchPlayfield.CENTER_X - width / 2, + X = CatchPlayfield.CENTER_X - width / 2, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs index 6af9c88088..f15da29993 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Tests { StartTime = 1000, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(0, -192) }), - OriginalX = CatchPlayfield.WIDTH / 2 + X = CatchPlayfield.WIDTH / 2 } } }, diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs index d7835bd8c4..1ff31697b8 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests { beatmap.HitObjects.Add(new Fruit { - OriginalX = (0.5f + i / 2048f * (i % 10 - 5)) * CatchPlayfield.WIDTH, + X = (0.5f + i / 2048f * (i % 10 - 5)) * CatchPlayfield.WIDTH, StartTime = i * 100, NewCombo = i % 8 == 0 }); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index d57e8e027e..e8bb57cdf3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Catch.Tests JudgementResult result2 = null; AddStep("catch hyper fruit", () => { - attemptCatch(new Fruit { HyperDashTarget = new Fruit { OriginalX = 100 } }, out drawableObject1, out result1); + attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }, out drawableObject1, out result1); }); AddStep("catch normal fruit", () => { @@ -107,14 +107,14 @@ namespace osu.Game.Rulesets.Catch.Tests var halfWidth = Catcher.CalculateCatchWidth(new BeatmapDifficulty { CircleSize = 0 }) / 2; AddStep("catch fruit", () => { - attemptCatch(new Fruit { OriginalX = -halfWidth + 1 }); - attemptCatch(new Fruit { OriginalX = halfWidth - 1 }); + attemptCatch(new Fruit { X = -halfWidth + 1 }); + attemptCatch(new Fruit { X = halfWidth - 1 }); }); checkPlate(2); AddStep("miss fruit", () => { - attemptCatch(new Fruit { OriginalX = -halfWidth - 1 }); - attemptCatch(new Fruit { OriginalX = halfWidth + 1 }); + attemptCatch(new Fruit { X = -halfWidth - 1 }); + attemptCatch(new Fruit { X = halfWidth + 1 }); }); checkPlate(2); } @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Catch.Tests [Test] public void TestFruitChangesCatcherState() { - AddStep("miss fruit", () => attemptCatch(new Fruit { OriginalX = 100 })); + AddStep("miss fruit", () => attemptCatch(new Fruit { X = 100 })); checkState(CatcherAnimationState.Fail); AddStep("catch fruit", () => attemptCatch(new Fruit())); checkState(CatcherAnimationState.Idle); @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper fruit", () => attemptCatch(new Fruit { - HyperDashTarget = new Fruit { OriginalX = 100 } + HyperDashTarget = new Fruit { X = 100 } })); checkHyperDash(true); AddStep("catch normal fruit", () => attemptCatch(new Fruit())); @@ -147,10 +147,10 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit { - HyperDashTarget = new Fruit { OriginalX = 100 } + HyperDashTarget = new Fruit { X = 100 } })); AddStep("catch tiny droplet", () => attemptCatch(new TinyDroplet())); - AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { OriginalX = 100 })); + AddStep("miss tiny droplet", () => attemptCatch(new TinyDroplet { X = 100 })); // catcher state and hyper dash state is preserved checkState(CatcherAnimationState.Kiai); checkHyperDash(true); @@ -161,9 +161,9 @@ namespace osu.Game.Rulesets.Catch.Tests { AddStep("catch hyper kiai fruit", () => attemptCatch(new TestKiaiFruit { - HyperDashTarget = new Fruit { OriginalX = 100 } + HyperDashTarget = new Fruit { X = 100 } })); - AddStep("miss banana", () => attemptCatch(new Banana { OriginalX = 100 })); + AddStep("miss banana", () => attemptCatch(new Banana { X = 100 })); // catcher state is preserved but hyper dash state is reset checkState(CatcherAnimationState.Kiai); checkHyperDash(false); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 423c3b7a13..5079e57e5e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Tests AddStep("catch fruit", () => attemptCatch(new Fruit())); AddStep("catch fruit last in combo", () => attemptCatch(new Fruit { LastInCombo = true })); AddStep("catch kiai fruit", () => attemptCatch(new TestSceneCatcher.TestKiaiFruit())); - AddStep("miss last in combo", () => attemptCatch(new Fruit { OriginalX = 100, LastInCombo = true })); + AddStep("miss last in combo", () => attemptCatch(new Fruit { X = 100, LastInCombo = true })); } private void attemptCatch(Fruit fruit) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 2db534e8c9..3e4995482d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Tests { var fruit = new Fruit { - OriginalX = getXCoords(hit), + X = getXCoords(hit), LastInCombo = i % 4 == 0, StartTime = playfieldTime + 800 + (200 * i) }; @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Catch.Tests var juice = new JuiceStream { - OriginalX = xCoords, + X = xCoords, StartTime = playfieldTime + 1000, Path = new SliderPath(PathType.Linear, new[] { @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Catch.Tests { var banana = new Banana { - OriginalX = getXCoords(hit), + X = getXCoords(hit), LastInCombo = i % 4 == 0, StartTime = playfieldTime + 800 + (200 * i) }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 67af3c4420..db09b2bc6b 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -70,20 +70,20 @@ namespace osu.Game.Rulesets.Catch.Tests beatmap.ControlPointInfo.Add(0, new TimingControlPoint()); // Should produce a hyper-dash (edge case test) - beatmap.HitObjects.Add(new Fruit { StartTime = 1816, OriginalX = 56, NewCombo = true }); - beatmap.HitObjects.Add(new Fruit { StartTime = 2008, OriginalX = 308, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); double startTime = 3000; const float left_x = 0.02f * CatchPlayfield.WIDTH; const float right_x = 0.98f * CatchPlayfield.WIDTH; - createObjects(() => new Fruit { OriginalX = left_x }); + createObjects(() => new Fruit { X = left_x }); createObjects(() => new TestJuiceStream(right_x), 1); createObjects(() => new TestJuiceStream(left_x), 1); - createObjects(() => new Fruit { OriginalX = right_x }); - createObjects(() => new Fruit { OriginalX = left_x }); - createObjects(() => new Fruit { OriginalX = right_x }); + createObjects(() => new Fruit { X = right_x }); + createObjects(() => new Fruit { X = left_x }); + createObjects(() => new Fruit { X = right_x }); createObjects(() => new TestJuiceStream(left_x), 1); beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.Tests { public TestJuiceStream(float x) { - OriginalX = x; + X = x; Path = new SliderPath(new[] { diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index dbcf382d62..269e783899 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Tests { new JuiceStream { - OriginalX = CatchPlayfield.CENTER_X, + X = CatchPlayfield.CENTER_X, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Tests }, new Banana { - OriginalX = CatchPlayfield.CENTER_X, + X = CatchPlayfield.CENTER_X, StartTime = 1000, NewCombo = true } diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 55e86a7be2..34964fc4ae 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps Path = curveData.Path, NodeSamples = curveData.NodeSamples, RepeatCount = curveData.RepeatCount, - OriginalX = positionData?.X ?? 0, + X = positionData?.X ?? 0, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0 @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps Samples = obj.Samples, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, - OriginalX = positionData?.X ?? 0 + X = positionData?.X ?? 0 }.Yield(); } } diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index ebbbd44960..e689d6a178 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -33,6 +33,14 @@ namespace osu.Game.Rulesets.Catch.Objects float IHasXPosition.X => OriginalX; + /// + /// An alias of setter. + /// + public float X + { + set => OriginalX = value; + } + public readonly Bindable EffectiveXBindable = new Bindable(); /// diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index bda0457c83..35fd58826e 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new TinyDroplet { StartTime = t + lastEvent.Value.Time, - OriginalX = OriginalX + Path.PositionAt( + X = OriginalX + Path.PositionAt( lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X, }); } @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = dropletSamples, StartTime = e.Time, - OriginalX = OriginalX + Path.PositionAt(e.PathProgress).X, + X = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = this.GetNodeSamples(nodeIndex++), StartTime = e.Time, - OriginalX = OriginalX + Path.PositionAt(e.PathProgress).X, + X = OriginalX + Path.PositionAt(e.PathProgress).X, }); break; } From 0ad256a7626c6aa28c97f64ecc9bc9a1940c2f87 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 13:18:32 +0900 Subject: [PATCH 10/12] Fix comment --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e689d6a178..6267eca7de 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Objects private float xOffset; /// - /// A random offset applied to the horizontal value, set by the . + /// A random offset applied to the horizontal position, set by the . /// internal float XOffset { From 5b5e883904298074b80671e87e0b88eca883127c Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 14 Dec 2020 13:39:07 +0900 Subject: [PATCH 11/12] Remove EffectiveXBindable (setting Value was not handled) And use orthogonal `OriginalXBindable` and `XOffsetBindable`. --- .../TestSceneCatcherArea.cs | 2 +- .../Objects/CatchHitObject.cs | 52 +++++++------------ .../Drawables/DrawableCatchHitObject.cs | 9 ++-- .../DrawablePalpableCatchHitObject.cs | 6 +-- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 5079e57e5e..1cbfa6338e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.Tests private void attemptCatch(Fruit fruit) { - fruit.OriginalX += catcher.X; + fruit.X = fruit.OriginalX + catcher.X; fruit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 6267eca7de..ae45182960 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -4,7 +4,6 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -21,46 +20,40 @@ namespace osu.Game.Rulesets.Catch.Objects /// /// The horizontal position of the hit object between 0 and . /// - /// - /// This value is the original value specified in the beatmap, not affected by beatmap processing. - /// It should be used instead of when working on a beatmap, not a gameplay. - /// - public float OriginalX + public float X { - get => OriginalXBindable.Value; set => OriginalXBindable.Value = value; } - float IHasXPosition.X => OriginalX; + float IHasXPosition.X => OriginalXBindable.Value; + + public readonly Bindable XOffsetBindable = new Bindable(); /// - /// An alias of setter. + /// A random offset applied to the horizontal position, set by the beatmap processing. /// - public float X + public float XOffset { - set => OriginalX = value; + set => XOffsetBindable.Value = value; } - public readonly Bindable EffectiveXBindable = new Bindable(); + /// + /// The horizontal position of the hit object between 0 and . + /// + /// + /// This value is the original value specified in the beatmap, not affected by the beatmap processing. + /// Use for a gameplay. + /// + public float OriginalX => OriginalXBindable.Value; /// /// The effective horizontal position of the hit object between 0 and . /// - public float EffectiveX => EffectiveXBindable.Value; - - private float xOffset; - - /// - /// A random offset applied to the horizontal position, set by the . - /// - internal float XOffset - { - set - { - xOffset = value; - EffectiveXBindable.Value = OriginalX + xOffset; - } - } + /// + /// This value is the original value plus the offset applied by the beatmap processing. + /// Use if a value not affected by the offset is desired. + /// + public float EffectiveX => OriginalXBindable.Value + XOffsetBindable.Value; public double TimePreempt = 1000; @@ -127,10 +120,5 @@ namespace osu.Game.Rulesets.Catch.Objects } protected override HitWindows CreateHitWindows() => HitWindows.Empty; - - protected CatchHitObject() - { - OriginalXBindable.BindValueChanged(change => EffectiveXBindable.Value = change.NewValue + xOffset); - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index edd607a443..0c065948ef 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -15,7 +15,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { public abstract class DrawableCatchHitObject : DrawableHitObject { - public readonly Bindable EffectiveXBindable = new Bindable(); + public readonly Bindable OriginalXBindable = new Bindable(); + public readonly Bindable XOffsetBindable = new Bindable(); protected override double InitialLifetimeOffset => HitObject.TimePreempt; @@ -38,14 +39,16 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { base.OnApply(); - EffectiveXBindable.BindTo(HitObject.EffectiveXBindable); + OriginalXBindable.BindTo(HitObject.OriginalXBindable); + XOffsetBindable.BindTo(HitObject.XOffsetBindable); } protected override void OnFree() { base.OnFree(); - EffectiveXBindable.UnbindFrom(HitObject.EffectiveXBindable); + OriginalXBindable.UnbindFrom(HitObject.OriginalXBindable); + XOffsetBindable.UnbindFrom(HitObject.XOffsetBindable); } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index d3fa43c6b6..84af7922f9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -55,10 +55,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [BackgroundDependencyLoader] private void load() { - EffectiveXBindable.BindValueChanged(x => - { - X = x.NewValue; - }, true); + OriginalXBindable.BindValueChanged(_ => X = OriginalXBindable.Value + XOffsetBindable.Value); + XOffsetBindable.BindValueChanged(_ => X = OriginalXBindable.Value + XOffsetBindable.Value, true); ScaleBindable.BindValueChanged(scale => { From b81dbfc1921dabe9b846d752c7b4ca2a2a347c6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Dec 2020 13:56:46 +0900 Subject: [PATCH 12/12] Move shared implementation to a named function --- .../Objects/Drawables/DrawablePalpableCatchHitObject.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index 84af7922f9..27cd7ed2bc 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -55,8 +55,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [BackgroundDependencyLoader] private void load() { - OriginalXBindable.BindValueChanged(_ => X = OriginalXBindable.Value + XOffsetBindable.Value); - XOffsetBindable.BindValueChanged(_ => X = OriginalXBindable.Value + XOffsetBindable.Value, true); + OriginalXBindable.BindValueChanged(updateXPosition); + XOffsetBindable.BindValueChanged(updateXPosition, true); ScaleBindable.BindValueChanged(scale => { @@ -67,6 +67,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables IndexInBeatmap.BindValueChanged(_ => UpdateComboColour()); } + private void updateXPosition(ValueChangedEvent _) + { + X = OriginalXBindable.Value + XOffsetBindable.Value; + } + protected override void OnApply() { base.OnApply();