1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-23 20:47:30 +08:00

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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing; 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. /// Ensures alternation is reset before the first hitobject after a break.
/// </summary> /// </summary>
[Test] [Test]
public void TestInputSingularWithBreak() => CreateModTest(new ModTestData public void TestInputSingularWithBreak([Values] bool pressBeforeSecondObject) => CreateModTest(new ModTestData
{ {
Mod = new OsuModAlternate(), Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 2, 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. // first press to start alternate lock.
new OsuReplayFrame(500, new Vector2(100), OsuAction.LeftButton), new OsuReplayFrame(450, new Vector2(100), OsuAction.LeftButton),
new OsuReplayFrame(501, new Vector2(100)), new OsuReplayFrame(451, new Vector2(100)),
// 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. // press same key at second hitobject and ensure it has been hit.
new OsuReplayFrame(2500, new Vector2(500, 100), OsuAction.LeftButton), new OsuReplayFrame(2450, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(2501, new Vector2(500, 100)), new OsuReplayFrame(2451, new Vector2(500, 100)),
// press same key at third hitobject and ensure it has been missed. // press same key at third hitobject and ensure it has been missed.
new OsuReplayFrame(3000, new Vector2(500, 100), OsuAction.LeftButton), new OsuReplayFrame(2950, new Vector2(500, 100), OsuAction.LeftButton),
new OsuReplayFrame(3001, new Vector2(500, 100)), 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)),
}
).ToList()
}); });
} }
} }

View File

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