1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 20:22:55 +08:00

Merge pull request #9779 from peppy/fix-super-short-spinners

Fix very short spinners being impossible to complete
This commit is contained in:
Dan Balasescu 2020-08-06 13:43:42 +09:00 committed by GitHub
commit 6f5fbbe141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 15 deletions

View File

@ -17,32 +17,58 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
private int depthIndex; private int depthIndex;
public TestSceneSpinner() private TestDrawableSpinner drawableSpinner;
[TestCase(false)]
[TestCase(true)]
public void TestVariousSpinners(bool autoplay)
{ {
AddStep("Miss Big", () => SetContents(() => testSingle(2))); string term = autoplay ? "Hit" : "Miss";
AddStep("Miss Medium", () => SetContents(() => testSingle(5))); AddStep($"{term} Big", () => SetContents(() => testSingle(2, autoplay)));
AddStep("Miss Small", () => SetContents(() => testSingle(7))); AddStep($"{term} Medium", () => SetContents(() => testSingle(5, autoplay)));
AddStep("Hit Big", () => SetContents(() => testSingle(2, true))); AddStep($"{term} Small", () => SetContents(() => testSingle(7, autoplay)));
AddStep("Hit Medium", () => SetContents(() => testSingle(5, true)));
AddStep("Hit Small", () => SetContents(() => testSingle(7, true)));
} }
private Drawable testSingle(float circleSize, bool auto = false) [TestCase(false)]
[TestCase(true)]
public void TestLongSpinner(bool autoplay)
{ {
var spinner = new Spinner { StartTime = Time.Current + 2000, EndTime = Time.Current + 5000 }; AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 2000)));
AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult);
AddUntilStep("Check correct progress", () => drawableSpinner.Progress == (autoplay ? 1 : 0));
}
[TestCase(false)]
[TestCase(true)]
public void TestSuperShortSpinner(bool autoplay)
{
AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 200)));
AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult);
AddUntilStep("Short spinner implicitly completes", () => drawableSpinner.Progress == 1);
}
private Drawable testSingle(float circleSize, bool auto = false, double length = 3000)
{
const double delay = 2000;
var spinner = new Spinner
{
StartTime = Time.Current + delay,
EndTime = Time.Current + delay + length
};
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
var drawable = new TestDrawableSpinner(spinner, auto) drawableSpinner = new TestDrawableSpinner(spinner, auto)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Depth = depthIndex++ Depth = depthIndex++
}; };
foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>()) foreach (var mod in SelectedMods.Value.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable }); mod.ApplyToDrawableHitObjects(new[] { drawableSpinner });
return drawable; return drawableSpinner;
} }
private class TestDrawableSpinner : DrawableSpinner private class TestDrawableSpinner : DrawableSpinner

View File

@ -175,7 +175,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
/// <summary> /// <summary>
/// The completion progress of this spinner from 0..1 (clamped). /// The completion progress of this spinner from 0..1 (clamped).
/// </summary> /// </summary>
public float Progress => Math.Clamp(RotationTracker.CumulativeRotation / 360 / Spinner.SpinsRequired, 0, 1); public float Progress
{
get
{
if (Spinner.SpinsRequired == 0)
// some spinners are so short they can't require an integer spin count.
// these become implicitly hit.
return 1;
return Math.Clamp(RotationTracker.CumulativeRotation / 360 / Spinner.SpinsRequired, 0, 1);
}
}
protected override void CheckForResult(bool userTriggered, double timeOffset) protected override void CheckForResult(bool userTriggered, double timeOffset)
{ {

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
@ -45,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects
double minimumRotationsPerSecond = stable_matching_fudge * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5); double minimumRotationsPerSecond = stable_matching_fudge * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5);
SpinsRequired = (int)Math.Max(1, (secondsDuration * minimumRotationsPerSecond)); SpinsRequired = (int)(secondsDuration * minimumRotationsPerSecond);
MaximumBonusSpins = (int)((maximum_rotations_per_second - minimumRotationsPerSecond) * secondsDuration); MaximumBonusSpins = (int)((maximum_rotations_per_second - minimumRotationsPerSecond) * secondsDuration);
} }