Merge pull request #20368 from Drison64/fix-catch-clamp

Fixed osu!catch objects spawning outside of playfield
This commit is contained in:
Dean Herbert
2022-09-22 13:37:23 +09:00
committed by GitHub
3 changed files with 31 additions and 10 deletions

View File

@ -106,20 +106,37 @@ namespace osu.Game.Rulesets.Catch.Tests
public void TestCatcherCatchWidth() public void TestCatcherCatchWidth()
{ {
float halfWidth = Catcher.CalculateCatchWidth(new BeatmapDifficulty { CircleSize = 0 }) / 2; float halfWidth = Catcher.CalculateCatchWidth(new BeatmapDifficulty { CircleSize = 0 }) / 2;
AddStep("move catcher to center", () => catcher.X = CatchPlayfield.CENTER_X);
float leftPlateBounds = CatchPlayfield.CENTER_X - halfWidth;
float rightPlateBounds = CatchPlayfield.CENTER_X + halfWidth;
AddStep("catch fruit", () => AddStep("catch fruit", () =>
{ {
attemptCatch(new Fruit { X = -halfWidth + 1 }); attemptCatch(new Fruit { X = leftPlateBounds + 1 });
attemptCatch(new Fruit { X = halfWidth - 1 }); attemptCatch(new Fruit { X = rightPlateBounds - 1 });
}); });
checkPlate(2); checkPlate(2);
AddStep("miss fruit", () => AddStep("miss fruit", () =>
{ {
attemptCatch(new Fruit { X = -halfWidth - 1 }); attemptCatch(new Fruit { X = leftPlateBounds - 1 });
attemptCatch(new Fruit { X = halfWidth + 1 }); attemptCatch(new Fruit { X = rightPlateBounds + 1 });
}); });
checkPlate(2); checkPlate(2);
} }
[Test]
public void TestFruitClampedToCatchableRegion()
{
AddStep("catch fruit left", () => attemptCatch(new Fruit { X = -CatchPlayfield.WIDTH }));
checkPlate(1);
AddStep("move catcher to right", () => catcher.X = CatchPlayfield.WIDTH);
AddStep("catch fruit right", () => attemptCatch(new Fruit { X = CatchPlayfield.WIDTH * 2 }));
checkPlate(2);
}
[Test] [Test]
public void TestFruitChangesCatcherState() public void TestFruitChangesCatcherState()
{ {

View File

@ -3,6 +3,7 @@
#nullable disable #nullable disable
using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -69,7 +70,7 @@ namespace osu.Game.Rulesets.Catch.Objects
/// This value is the original <see cref="X"/> value plus the offset applied by the beatmap processing. /// This value is the original <see cref="X"/> value plus the offset applied by the beatmap processing.
/// Use <see cref="OriginalX"/> if a value not affected by the offset is desired. /// Use <see cref="OriginalX"/> if a value not affected by the offset is desired.
/// </remarks> /// </remarks>
public float EffectiveX => OriginalX + XOffset; public float EffectiveX => Math.Clamp(OriginalX + XOffset, 0, CatchPlayfield.WIDTH);
public double TimePreempt { get; set; } = 1000; public double TimePreempt { get; set; } = 1000;

View File

@ -11,6 +11,7 @@ using Newtonsoft.Json;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -84,8 +85,8 @@ namespace osu.Game.Rulesets.Catch.Objects
AddNested(new TinyDroplet AddNested(new TinyDroplet
{ {
StartTime = t + lastEvent.Value.Time, StartTime = t + lastEvent.Value.Time,
X = OriginalX + Path.PositionAt( X = ClampToPlayfield(EffectiveX + Path.PositionAt(
lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X, lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X),
}); });
} }
} }
@ -102,7 +103,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
Samples = dropletSamples, Samples = dropletSamples,
StartTime = e.Time, StartTime = e.Time,
X = OriginalX + Path.PositionAt(e.PathProgress).X, X = ClampToPlayfield(EffectiveX + Path.PositionAt(e.PathProgress).X),
}); });
break; break;
@ -113,14 +114,16 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
Samples = this.GetNodeSamples(nodeIndex++), Samples = this.GetNodeSamples(nodeIndex++),
StartTime = e.Time, StartTime = e.Time,
X = OriginalX + Path.PositionAt(e.PathProgress).X, X = ClampToPlayfield(EffectiveX + Path.PositionAt(e.PathProgress).X),
}); });
break; break;
} }
} }
} }
public float EndX => OriginalX + this.CurvePositionAt(1).X; public float EndX => ClampToPlayfield(EffectiveX + this.CurvePositionAt(1).X);
public float ClampToPlayfield(float value) => Math.Clamp(value, 0, CatchPlayfield.WIDTH);
[JsonIgnore] [JsonIgnore]
public double Duration public double Duration