Merge pull request #20346 from frenzibyte/fix-input-blocking-mod

Fix `InputBlockingMod` not always clearing last action on break periods
This commit is contained in:
Dean Herbert 2022-09-19 22:18:24 +09:00 committed by GitHub
commit d4510b72da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 16 deletions

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
@ -125,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
/// Ensures alternation is reset before the first hitobject after a break.
/// </summary>
[Test]
public void TestInputSingularWithBreak() => CreateModTest(new ModTestData
public void TestInputSingularWithBreak([Values] bool pressBeforeSecondObject) => CreateModTest(new ModTestData
{
Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 2,
@ -155,21 +156,26 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
},
}
},
ReplayFrames = new List<ReplayFrame>
ReplayFrames = new ReplayFrame[]
{
// first press to start alternate lock.
new OsuReplayFrame(500, new Vector2(100), OsuAction.LeftButton),
new OsuReplayFrame(501, new Vector2(100)),
new OsuReplayFrame(450, new Vector2(100), OsuAction.LeftButton),
new OsuReplayFrame(451, new Vector2(100)),
// press same key at second hitobject and ensure it has been hit.
new OsuReplayFrame(2450, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(2451, new Vector2(500, 100)),
// press same key at third hitobject and ensure it has been missed.
new OsuReplayFrame(2950, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(2951, new Vector2(500, 100)),
}.Concat(!pressBeforeSecondObject
? Enumerable.Empty<ReplayFrame>()
: new ReplayFrame[]
{
// press same key after break but before hit object.
new OsuReplayFrame(2250, new Vector2(300, 100), OsuAction.LeftButton),
new OsuReplayFrame(2251, new Vector2(300, 100)),
// press same key at second hitobject and ensure it has been hit.
new OsuReplayFrame(2500, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(2501, new Vector2(500, 100)),
// press same key at third hitobject and ensure it has been missed.
new OsuReplayFrame(3000, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(3001, new Vector2(500, 100)),
}
).ToList()
});
}
}

View File

@ -18,7 +18,7 @@ using osu.Game.Utils;
namespace osu.Game.Rulesets.Osu.Mods
{
public abstract class InputBlockingMod : Mod, IApplicableToDrawableRuleset<OsuHitObject>
public abstract class InputBlockingMod : Mod, IApplicableToDrawableRuleset<OsuHitObject>, IUpdatableByPlayfield
{
public override double ScoreMultiplier => 1.0;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax), typeof(OsuModCinema) };
@ -62,15 +62,18 @@ namespace osu.Game.Rulesets.Osu.Mods
gameplayClock = drawableRuleset.FrameStableClock;
}
public void Update(Playfield playfield)
{
if (LastAcceptedAction != null && nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime))
LastAcceptedAction = null;
}
protected abstract bool CheckValidNewAction(OsuAction action);
private bool checkCorrectAction(OsuAction action)
{
if (nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime))
{
LastAcceptedAction = null;
return true;
}
switch (action)
{