From e0426836c19391139a2976ea364ed0122c94aa77 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Fri, 5 Aug 2022 16:30:07 +0200 Subject: [PATCH] Make swells and drumrolls optional by default --- .../Mods/TestSceneTaikoModClassic.cs | 80 ---------- .../Mods/TestSceneTaikoModPerfect.cs | 4 +- .../TestSceneTaikoSuddenDeath.cs | 4 +- .../Judgements/TaikoDrumRollJudgement.cs | 13 +- .../Judgements/TaikoDrumRollTickJudgement.cs | 14 +- .../Judgements/TaikoSwellJudgement.cs | 7 +- .../Mods/TaikoModClassic.cs | 151 +----------------- .../Objects/Drawables/DrawableDrumRoll.cs | 13 +- .../Objects/Drawables/DrawableSwell.cs | 10 +- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 33 +--- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 3 - 11 files changed, 24 insertions(+), 308 deletions(-) delete mode 100644 osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModClassic.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModClassic.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModClassic.cs deleted file mode 100644 index 9028f411ce..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModClassic.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using NUnit.Framework; -using osu.Game.Rulesets.Replays; -using osu.Game.Rulesets.Taiko.Beatmaps; -using osu.Game.Rulesets.Taiko.Mods; -using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Rulesets.Taiko.Replays; - -namespace osu.Game.Rulesets.Taiko.Tests.Mods -{ - public class TestSceneTaikoModClassic : TaikoModTestScene - { - [Test] - public void TestHittingDrumRollsIsOptional() => CreateModTest(new ModTestData - { - Mod = new TaikoModClassic(), - Autoplay = false, - Beatmap = new TaikoBeatmap - { - BeatmapInfo = { Ruleset = CreatePlayerRuleset().RulesetInfo }, - HitObjects = new List - { - new Hit - { - StartTime = 1000, - Type = HitType.Centre - }, - new DrumRoll - { - StartTime = 3000, - EndTime = 6000 - } - } - }, - ReplayFrames = new List - { - new TaikoReplayFrame(1000, TaikoAction.LeftCentre), - new TaikoReplayFrame(1001) - }, - PassCondition = () => Player.ScoreProcessor.HasCompleted.Value - && Player.ScoreProcessor.Combo.Value == 1 - && Player.ScoreProcessor.Accuracy.Value == 1 - }); - - [Test] - public void TestHittingSwellsIsOptional() => CreateModTest(new ModTestData - { - Mod = new TaikoModClassic(), - Autoplay = false, - Beatmap = new TaikoBeatmap - { - BeatmapInfo = { Ruleset = CreatePlayerRuleset().RulesetInfo }, - HitObjects = new List - { - new Hit - { - StartTime = 1000, - Type = HitType.Centre - }, - new Swell - { - StartTime = 3000, - EndTime = 6000 - } - } - }, - ReplayFrames = new List - { - new TaikoReplayFrame(1000, TaikoAction.LeftCentre), - new TaikoReplayFrame(1001) - }, - PassCondition = () => Player.ScoreProcessor.HasCompleted.Value - && Player.ScoreProcessor.Combo.Value == 1 - && Player.ScoreProcessor.Accuracy.Value == 1 - }); - } -} diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs index a83cc16413..92503a9f03 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs @@ -25,11 +25,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new DrumRoll { StartTime = 1000, EndTime = 3000 }), shouldMiss); + public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new DrumRoll { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); [TestCase(false)] [TestCase(true)] - public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss); + public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Swell { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); private class TestTaikoRuleset : TaikoRuleset { diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs index cdfab4a215..2169ac5581 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Tests }; [Test] - public void TestSpinnerDoesFail() + public void TestSwellDoesNotFail() { bool judged = false; AddStep("Setup judgements", () => @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Player.ScoreProcessor.NewJudgement += _ => judged = true; }); AddUntilStep("swell judged", () => judged); - AddAssert("failed", () => Player.GameplayState.HasFailed); + AddAssert("not failed", () => !Player.GameplayState.HasFailed); } } } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs index be128d85b5..f7f923e76e 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs @@ -9,17 +9,8 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoDrumRollJudgement : TaikoJudgement { - protected override double HealthIncreaseFor(HitResult result) - { - // Drum rolls can be ignored with no health penalty - switch (result) - { - case HitResult.Miss: - return 0; + public override HitResult MaxResult => HitResult.IgnoreHit; - default: - return base.HealthIncreaseFor(result); - } - } + protected override double HealthIncreaseFor(HitResult result) => 0; } } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 5f2587a5d5..de56c76f56 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -9,18 +9,8 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoDrumRollTickJudgement : TaikoJudgement { - public override HitResult MaxResult => HitResult.SmallTickHit; + public override HitResult MaxResult => HitResult.SmallBonus; - protected override double HealthIncreaseFor(HitResult result) - { - switch (result) - { - case HitResult.SmallTickHit: - return 0.15; - - default: - return 0; - } - } + protected override double HealthIncreaseFor(HitResult result) => 0; } } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs index 6d469bd1d7..146621997d 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs @@ -9,16 +9,13 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoSwellJudgement : TaikoJudgement { - /// - /// The to grant when the player has hit more than half of swell ticks. - /// - public virtual HitResult PartialCompletionResult => HitResult.Ok; + public override HitResult MaxResult => HitResult.LargeBonus; protected override double HealthIncreaseFor(HitResult result) { switch (result) { - case HitResult.Miss: + case HitResult.IgnoreMiss: return -0.65; default: diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs index 28124d16e1..f7fdd447d6 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs @@ -1,170 +1,27 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Beatmaps; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko.Mods { - public class TaikoModClassic : ModClassic, IApplicableToDrawableRuleset, IUpdatableByPlayfield, IApplicableAfterBeatmapConversion + public class TaikoModClassic : ModClassic, IApplicableToDrawableRuleset, IUpdatableByPlayfield { private DrawableTaikoRuleset? drawableTaikoRuleset; public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - var playfield = (TaikoPlayfield)drawableRuleset.Playfield; - playfield.ClassicHitTargetPosition.Value = true; - drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; drawableTaikoRuleset.LockPlayfieldAspect.Value = false; - drawableTaikoRuleset.Playfield.RegisterPool(5); - drawableTaikoRuleset.Playfield.RegisterPool(100); - drawableTaikoRuleset.Playfield.RegisterPool(5); + var playfield = (TaikoPlayfield)drawableRuleset.Playfield; + playfield.ClassicHitTargetPosition.Value = true; } - public void ApplyToBeatmap(IBeatmap beatmap) - { - var taikoBeatmap = (TaikoBeatmap)beatmap; - - if (taikoBeatmap.HitObjects.Count == 0) return; - - var hitObjects = taikoBeatmap.HitObjects.Select(ho => - { - switch (ho) - { - case DrumRoll drumRoll: - return new ClassicDrumRoll(drumRoll); - - case Swell swell: - return new ClassicSwell(swell); - - default: - return ho; - } - }).ToList(); - - taikoBeatmap.HitObjects = hitObjects; - } - - #region Classic drum roll - - private class TaikoClassicDrumRollJudgement : TaikoDrumRollJudgement - { - public override HitResult MaxResult => HitResult.IgnoreHit; - } - - private class ClassicDrumRoll : DrumRoll - { - public ClassicDrumRoll(DrumRoll original) - { - StartTime = original.StartTime; - Samples = original.Samples; - EndTime = original.EndTime; - Duration = original.Duration; - TickRate = original.TickRate; - RequiredGoodHits = original.RequiredGoodHits; - RequiredGreatHits = original.RequiredGreatHits; - } - - public override Judgement CreateJudgement() => new TaikoClassicDrumRollJudgement(); - - protected override List CreateTicks(CancellationToken cancellationToken) - { - List oldTicks = base.CreateTicks(cancellationToken); - - List newTicks = oldTicks.Select(oldTick => - { - if (oldTick is DrumRollTick drumRollTick) - { - return new ClassicDrumRollTick(drumRollTick); - } - - return oldTick; - }).ToList(); - - return newTicks; - } - } - - private class TaikoClassicDrumRollTickJudgement : TaikoDrumRollTickJudgement - { - public override HitResult MaxResult => HitResult.SmallBonus; - } - - private class ClassicDrumRollTick : DrumRollTick - { - public override Judgement CreateJudgement() => new TaikoClassicDrumRollTickJudgement(); - - public ClassicDrumRollTick(DrumRollTick original) - { - StartTime = original.StartTime; - Samples = original.Samples; - FirstTick = original.FirstTick; - TickSpacing = original.TickSpacing; - } - } - - private class ClassicDrawableDrumRoll : DrawableDrumRoll - { - public override bool DisplayResult => false; - - protected override void CheckForResult(bool userTriggered, double timeOffset) - { - if (userTriggered) - return; - - if (timeOffset < 0) - return; - - ApplyResult(r => r.Type = HitResult.IgnoreHit); - } - } - - #endregion - - #region Classic swell - - private class TaikoClassicSwellJudgement : TaikoSwellJudgement - { - public override HitResult MaxResult => HitResult.LargeBonus; - - public override HitResult PartialCompletionResult => HitResult.SmallBonus; - } - - private class ClassicSwell : Swell - { - public ClassicSwell(Swell original) - { - StartTime = original.StartTime; - Samples = original.Samples; - EndTime = original.EndTime; - Duration = original.Duration; - RequiredHits = original.RequiredHits; - } - - public override Judgement CreateJudgement() => new TaikoClassicSwellJudgement(); - } - - private class ClassicDrawableSwell : DrawableSwell - { - public override bool DisplayResult => false; - } - - #endregion - public void Update(Playfield playfield) { Debug.Assert(drawableTaikoRuleset != null); @@ -172,8 +29,6 @@ namespace osu.Game.Rulesets.Taiko.Mods // Classic taiko scrolls at a constant 100px per 1000ms. More notes become visible as the playfield is lengthened. const float scroll_rate = 10; - Debug.Assert(drawableTaikoRuleset != null); - // Since the time range will depend on a positional value, it is referenced to the x480 pixel space. float ratio = drawableTaikoRuleset.DrawHeight / 480; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 04ed6d0b87..418c4673e2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -4,7 +4,6 @@ #nullable disable using System; -using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Utils; @@ -16,7 +15,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; using osuTK; @@ -40,6 +38,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private Color4 colourIdle; private Color4 colourEngaged; + public override bool DisplayResult => false; + public DrawableDrumRoll() : this(null) { @@ -140,14 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (timeOffset < 0) return; - int countHit = NestedHitObjects.Count(o => o.IsHit); - - if (countHit >= HitObject.RequiredGoodHits) - { - ApplyResult(r => r.Type = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Ok); - } - else - ApplyResult(r => r.Type = r.Judgement.MinResult); + ApplyResult(r => r.Type = r.Judgement.MinResult); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index a90e9ce676..84edb30890 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Taiko.Judgements; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; @@ -39,6 +39,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private readonly CircularContainer targetRing; private readonly CircularContainer expandingRing; + public override bool DisplayResult => false; + public DrawableSwell() : this(null) { @@ -222,11 +224,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables tick.TriggerResult(false); } - ApplyResult(r => - { - var swellJudgement = (TaikoSwellJudgement)r.Judgement; - r.Type = numHits > HitObject.RequiredHits / 2 ? swellJudgement.PartialCompletionResult : swellJudgement.MinResult; - }); + ApplyResult(r => r.Type = numHits > HitObject.RequiredHits / 2 ? HitResult.SmallBonus : r.Judgement.MinResult); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 21c7f13fec..db752c6691 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -4,8 +4,6 @@ #nullable disable using osu.Game.Rulesets.Objects.Types; -using System; -using System.Collections.Generic; using System.Threading; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -43,24 +41,12 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public int TickRate = 1; - /// - /// Number of drum roll ticks required for a "Good" hit. - /// - public double RequiredGoodHits { get; protected set; } - - /// - /// Number of drum roll ticks required for a "Great" hit. - /// - public double RequiredGreatHits { get; protected set; } - /// /// The length (in milliseconds) between ticks of this drumroll. /// Half of this value is the hit window of the ticks. /// private double tickSpacing = 100; - private float overallDifficulty = BeatmapDifficulty.DEFAULT_DIFFICULTY; - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); @@ -71,28 +57,19 @@ namespace osu.Game.Rulesets.Taiko.Objects Velocity = scoringDistance / timingPoint.BeatLength; tickSpacing = timingPoint.BeatLength / TickRate; - overallDifficulty = difficulty.OverallDifficulty; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) { - foreach (TaikoHitObject tick in CreateTicks(cancellationToken)) - { - AddNested(tick); - } - - RequiredGoodHits = NestedHitObjects.Count * Math.Min(0.15, 0.05 + 0.10 / 6 * overallDifficulty); - RequiredGreatHits = NestedHitObjects.Count * Math.Min(0.30, 0.10 + 0.20 / 6 * overallDifficulty); + createTicks(cancellationToken); base.CreateNestedHitObjects(cancellationToken); } - protected virtual List CreateTicks(CancellationToken cancellationToken) + private void createTicks(CancellationToken cancellationToken) { - List ticks = new List(); - if (tickSpacing == 0) - return ticks; + return; bool first = true; @@ -100,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.Objects { cancellationToken.ThrowIfCancellationRequested(); - ticks.Add(new DrumRollTick + AddNested(new DrumRollTick { FirstTick = first, TickSpacing = tickSpacing, @@ -110,8 +87,6 @@ namespace osu.Game.Rulesets.Taiko.Objects first = false; } - - return ticks; } public override Judgement CreateJudgement() => new TaikoDrumRollJudgement(); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index eb0706f131..499bb8cf1d 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -196,9 +196,6 @@ namespace osu.Game.Rulesets.Taiko { switch (result) { - case HitResult.SmallTickHit: - return "drum tick"; - case HitResult.SmallBonus: return "bonus"; }