From 68d76d4380f2816088cd7f0344331e79aa4df907 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 23 Dec 2017 20:58:09 +0900 Subject: [PATCH 01/10] Fix taiko strong hits not being handled --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d960ab6b48..c397ea47ef 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { judgementOccurred = false; - if (AllJudged || State != ArmedState.Idle) + if (AllJudged) return false; if (NestedHitObjects != null) From 8529eb1d3a2350da13d8fb445a7d13375afa1c97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 14:49:39 +0900 Subject: [PATCH 02/10] Make strong hit misses not count as misses --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 81b23af1a9..07f7b83cef 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (timeOffset > second_hit_window) - AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.Miss }); + AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.None }); return; } From 844e39a9f6f177be8bc4f41fe8ff69425052d622 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:04:22 +0900 Subject: [PATCH 03/10] Make Swells play samples while they're being hit --- .../Objects/Drawables/DrawableSwell.cs | 37 ++++++++++++++----- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 28 +++++++++++++- .../Objects/SwellSampleMapping.cs | 28 ++++++++++++++ .../osu.Game.Rulesets.Taiko.csproj | 1 + 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 738902846b..d657598554 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,6 +14,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; +using osu.Framework.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -34,10 +35,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private readonly CircularContainer targetRing; private readonly CircularContainer expandingRing; - private readonly TaikoAction[] rimActions = { TaikoAction.LeftRim, TaikoAction.RightRim }; - private readonly TaikoAction[] centreActions = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; - private TaikoAction[] lastAction; - /// /// The amount of times the user has hit this swell. /// @@ -120,11 +117,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, AudioManager audio) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); + + foreach (var mapping in HitObject.ProgressionSamples) + mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -205,22 +205,39 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } + private bool? lastWasCentre; + public override bool OnPressed(TaikoAction action) { // Don't handle keys before the swell starts if (Time.Current < HitObject.StartTime) return false; - // Find the keyset which this key corresponds to - var keySet = rimActions.Contains(action) ? rimActions : centreActions; + var isCentre = action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre; - // Ensure alternating keysets - if (keySet == lastAction) + // Ensure alternating centre and rim hits + if (lastWasCentre == isCentre) return false; - lastAction = keySet; + lastWasCentre = isCentre; UpdateJudgement(true); + if (AllJudged) + return true; + + // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects + // This causes the playfield to not play sounds, so they need to be handled locally + + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; + + var mapping = HitObject.ProgressionSamples[mappingIndex]; + if (isCentre) + mapping.CentreChannel.Play(); + else + mapping.RimChannel.Play(); + return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index f74a543ca9..b4fa736045 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,6 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Taiko.Objects @@ -15,5 +20,26 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; + + public List ProgressionSamples = new List(); + + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + + var progressionSamplePoints = + new[] { controlPointInfo.SamplePointAt(StartTime) } + .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); + + foreach (var point in progressionSamplePoints) + { + ProgressionSamples.Add(new SwellSampleMapping + { + Time = point.Time, + Centre = point.GetSampleInfo(), + Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) + }); + } + } } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs new file mode 100644 index 0000000000..99d0e1d0fd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; + +namespace osu.Game.Rulesets.Taiko.Objects +{ + public class SwellSampleMapping : IComparable + { + public double Time; + public SampleInfo Centre; + public SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index bb02db62b9..9fa3936153 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -74,6 +74,7 @@ + From d288d8a51f370a6f91141c046ad3a67b4a1a6c5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:35:28 +0900 Subject: [PATCH 04/10] Remove SampleInfoList --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++--- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 3 ++- .../Legacy/EndTimeObjectPatternGenerator.cs | 3 ++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 6 +++--- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 3 ++- .../Tests/TestCaseTaikoPlayfield.cs | 14 ++++++++++++-- osu.Game/Audio/SampleInfoList.cs | 18 ------------------ osu.Game/Rulesets/Objects/HitObject.cs | 2 +- .../Legacy/Catch/ConvertHitObjectParser.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 8 ++++---- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Legacy/Mania/ConvertHitObjectParser.cs | 2 +- .../Legacy/Osu/ConvertHitObjectParser.cs | 4 ++-- .../Legacy/Taiko/ConvertHitObjectParser.cs | 4 ++-- osu.Game/Rulesets/Objects/Types/IHasRepeats.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 18 files changed, 41 insertions(+), 47 deletions(-) delete mode 100644 osu.Game/Audio/SampleInfoList.cs diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 8e496c3b0c..7d0d80a0ce 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = lastTickTime, ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = repeatStartTime + t, ComboColour = ComboColour, X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Catch.Objects set { Curve.ControlPoints = value; } } - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public CurveType CurveType { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d5a799b4ed..407d4db143 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 270c264e0c..8251dea5f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -435,7 +436,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3e9fc1ae27..8e832960df 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; using osu.Game.Rulesets.Objects; @@ -77,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy }; if (hold.Head.Samples == null) - hold.Head.Samples = new SampleInfoList(); + hold.Head.Samples = new List(); hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4f5a44e61d..5f9f11c783 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public int RepeatCount { get; set; } = 1; private int stackHeight; @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(RepeatSamples[repeat]) + Samples = new List(RepeatSamples[repeat]) }); } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 9b4a6c47a9..690b80b12c 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps var curveData = obj as IHasCurve; // Old osu! used hit sounding to determine various hit type information - SampleInfoList samples = obj.Samples; + List samples = obj.Samples; bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH); @@ -115,12 +115,12 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List allSamples = curveData != null ? curveData.RepeatSamples : new List(new[] { samples }); + List> allSamples = curveData != null ? curveData.RepeatSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { - SampleInfoList currentSamples = allSamples[i]; + List currentSamples = allSamples[i]; bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH); diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 4104b59979..5a566fd091 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Objects.Types; using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs index bca4806108..b1e6e9c4ce 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs @@ -165,11 +165,15 @@ namespace osu.Game.Rulesets.Taiko.Tests private void addSwell(double duration = default_duration) { - rulesetContainer.Playfield.Add(new DrawableSwell(new Swell + var swell = new Swell { StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, Duration = duration, - })); + }; + + swell.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + rulesetContainer.Playfield.Add(new DrawableSwell(swell)); } private void addDrumRoll(bool strong, double duration = default_duration) @@ -184,6 +188,8 @@ namespace osu.Game.Rulesets.Taiko.Tests Duration = duration, }; + d.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + rulesetContainer.Playfield.Add(new DrawableDrumRoll(d)); } @@ -195,6 +201,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h)); else @@ -209,6 +217,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h)); else diff --git a/osu.Game/Audio/SampleInfoList.cs b/osu.Game/Audio/SampleInfoList.cs deleted file mode 100644 index 06dd716a4a..0000000000 --- a/osu.Game/Audio/SampleInfoList.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; - -namespace osu.Game.Audio -{ - public class SampleInfoList : List - { - public SampleInfoList() - { - } - - public SampleInfoList(IEnumerable elements) : base(elements) - { - } - } -} \ No newline at end of file diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index e950516bf4..56f7a2e1a2 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public SampleInfoList Samples; + public List Samples; [JsonIgnore] public SampleControlPoint SampleControlPoint; diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 667f921e04..fbf02f5345 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 0d7d617405..bdbd7a9e65 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } // Generate the final per-node samples - var nodeSamples = new List(nodes); + var nodeSamples = new List>(nodes); for (int i = 0; i <= repeatCount; i++) nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider repeat count. /// The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples); /// /// Creates a legacy Spinner-type hit object. @@ -234,9 +234,9 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The hold end time. protected abstract HitObject CreateHold(Vector2 position, bool newCombo, double endTime); - private SampleInfoList convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) + private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { - var soundTypes = new SampleInfoList + var soundTypes = new List { new SampleInfo { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 698b74cc28..6dc8a07630 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance { get; set; } - public List RepeatSamples { get; set; } + public List> RepeatSamples { get; set; } public int RepeatCount { get; set; } = 1; public double EndTime => StartTime + RepeatCount * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 86dd40b06e..2060b84222 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index 24c205db13..0062d29446 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Osu { @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index 0554cfd97d..529a28ac15 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Taiko { @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 5abad2d661..2fe2424d49 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Types /// /// The samples to be played when each repeat node is hit (0 -> first repeat node, 1 -> second repeat node, etc). /// - List RepeatSamples { get; } + List> RepeatSamples { get; } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..1c5d20842d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,7 +239,6 @@ - From 0fb620a8d3c730da1f10d1d5ab45482d783a3b2d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:41:18 +0900 Subject: [PATCH 05/10] Make HitObject.Samples non-nullable --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++-- osu.Game/Rulesets/Objects/HitObject.cs | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index c397ea47ef..be161b9ad3 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -84,10 +84,11 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (HitObject.Samples != null) + if (Samples.Count > 0) { if (HitObject.SampleControlPoint == null) - throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SampleControlPoint)}."); + throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); foreach (SampleInfo s in HitObject.Samples) { diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 56f7a2e1a2..4f06f6afe1 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Objects /// public virtual double StartTime { get; set; } + private List samples; + /// /// The samples to be played when this hit object is hit. /// @@ -32,7 +34,11 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public List Samples; + public List Samples + { + get => samples ?? (samples = new List()); + set => samples = value; + } [JsonIgnore] public SampleControlPoint SampleControlPoint; From 8bfdee586b6cde7effbc17b8c3ae6b7ed1ae4dec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:47:29 +0900 Subject: [PATCH 06/10] Rename SwellSampleMapping -> DrumSampleMapping --- .../Audio/DrumSampleMapping.cs | 40 +++++++++++++++++++ .../Objects/Drawables/DrawableSwell.cs | 3 +- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 15 ++----- .../Objects/SwellSampleMapping.cs | 28 ------------- .../osu.Game.Rulesets.Taiko.csproj | 2 +- 5 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs delete mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs new file mode 100644 index 0000000000..25fa9951df --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; + +namespace osu.Game.Rulesets.Taiko.Audio +{ + public class DrumSampleMapping : IComparable + { + public double Time; + public readonly SampleInfo Centre; + public readonly SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public DrumSampleMapping() + { + } + + public DrumSampleMapping(SampleControlPoint samplePoint) + { + Time = samplePoint.Time; + Centre = samplePoint.GetSampleInfo(); + Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); + } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index d657598554..5131572abd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -15,6 +15,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; using osu.Framework.Audio; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -228,7 +229,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects // This causes the playfield to not play sounds, so they need to be handled locally - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); if (mappingIndex < 0) mappingIndex = ~mappingIndex - 1; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index b4fa736045..849c88ee4d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -7,6 +7,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { @@ -21,25 +22,17 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public int RequiredHits = 10; - public List ProgressionSamples = new List(); + public List ProgressionSamples = new List(); protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - var progressionSamplePoints = - new[] { controlPointInfo.SamplePointAt(StartTime) } + var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); foreach (var point in progressionSamplePoints) - { - ProgressionSamples.Add(new SwellSampleMapping - { - Time = point.Time, - Centre = point.GetSampleInfo(), - Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) - }); - } + ProgressionSamples.Add(new DrumSampleMapping(point)); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs deleted file mode 100644 index 99d0e1d0fd..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Game.Audio; - -namespace osu.Game.Rulesets.Taiko.Objects -{ - public class SwellSampleMapping : IComparable - { - public double Time; - public SampleInfo Centre; - public SampleInfo Rim; - - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public void RetrieveChannels(AudioManager audio) - { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); - } - - public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); - } -} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 9fa3936153..f1c29c1a34 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -44,6 +44,7 @@ + @@ -74,7 +75,6 @@ - From ac8b345bfebba4530c67bbf9d0087472825ace18 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:20 +0900 Subject: [PATCH 07/10] Make TaikoPlayfield use the new DrumSampleMapping --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 37 +++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 2cc95fc981..96ef86e3ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -23,6 +23,7 @@ using osu.Framework.Audio.Sample; using System.Collections.Generic; using osu.Game.Audio; using System; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; private readonly ControlPointInfo controlPointInfo; - private Dictionary drumSampleMappings; + private readonly List drumSampleMappings = new List(); public TaikoPlayfield(ControlPointInfo controlPointInfo) : base(Axes.X) @@ -207,15 +208,16 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - drumSampleMappings = new Dictionary(); - foreach (var s in controlPointInfo.SamplePoints) + // We may have 0 sample points, but we need at least the default one + var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } + .Concat(controlPointInfo.SamplePoints); + + foreach (var s in samplePoints) { - drumSampleMappings.Add(s, - new DrumSamples - { - Centre = s.GetSampleInfo().GetChannel(audio.Sample), - Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) - }); + var mapping = new DrumSampleMapping(s); + mapping.RetrieveChannels(audio); + + drumSampleMappings.Add(mapping); } overlayBackgroundContainer.BorderColour = colours.Gray0; @@ -285,25 +287,20 @@ namespace osu.Game.Rulesets.Taiko.UI public bool OnPressed(TaikoAction action) { - var samplePoint = controlPointInfo.SamplePointAt(Clock.CurrentTime); + var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; - if (!drumSampleMappings.TryGetValue(samplePoint, out var samples)) - throw new InvalidOperationException("Current sample set not found."); + var mapping = drumSampleMappings[mappingIndex]; if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - samples.Centre.Play(); + mapping.CentreChannel.Play(); else - samples.Rim.Play(); + mapping.RimChannel.Play(); return true; } public bool OnReleased(TaikoAction action) => false; - - private class DrumSamples - { - public SampleChannel Centre; - public SampleChannel Rim; - } } } From affdd81563b21d0fdfec753bc2dcdc46cb417ad9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:44 +0900 Subject: [PATCH 08/10] Remove unused usings --- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 1 - osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 849c88ee4d..714e5d29ee 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 96ef86e3ce..229e44cf27 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -19,10 +19,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using System.Collections.Generic; -using osu.Game.Audio; -using System; using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI From 14162b5d46a56f4f8da0e01829c25c67c331b1e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:23 +0900 Subject: [PATCH 09/10] Make InputDrum handle all Normals/Claps, hitobjects all others --- .../Audio/DrumSampleMapping.cs | 47 +++++++++++-------- .../Objects/Drawables/DrawableSwell.cs | 19 -------- .../Drawables/DrawableTaikoHitObject.cs | 7 +++ osu.Game.Rulesets.Taiko/Objects/Swell.cs | 13 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 36 ++++++++++++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 38 ++------------- .../Objects/Drawables/DrawableHitObject.cs | 6 ++- 7 files changed, 72 insertions(+), 94 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index 25fa9951df..9d0037b97a 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -1,7 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; +using System.Collections.Generic; +using System.Linq; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Game.Audio; @@ -9,32 +10,38 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Taiko.Audio { - public class DrumSampleMapping : IComparable + public class DrumSampleMapping { - public double Time; - public readonly SampleInfo Centre; - public readonly SampleInfo Rim; + private readonly ControlPointInfo controlPoints; + private readonly Dictionary mappings = new Dictionary(); - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public DrumSampleMapping() + public DrumSampleMapping(ControlPointInfo controlPoints, AudioManager audio) { + this.controlPoints = controlPoints; + + IEnumerable samplePoints; + if (controlPoints.SamplePoints.Count == 0) + // Get the default sample point + samplePoints = new[] { controlPoints.SamplePointAt(double.MinValue) }; + else + samplePoints = controlPoints.SamplePoints; + + foreach (var s in samplePoints.Distinct()) + { + mappings[s] = new DrumSample + { + Centre = s.GetSampleInfo().GetChannel(audio.Sample), + Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) + }; + } } - public DrumSampleMapping(SampleControlPoint samplePoint) - { - Time = samplePoint.Time; - Centre = samplePoint.GetSampleInfo(); - Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); - } + public DrumSample SampleAt(double time) => mappings[controlPoints.SamplePointAt(time)]; - public void RetrieveChannels(AudioManager audio) + public class DrumSample { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); + public SampleChannel Centre; + public SampleChannel Rim; } - - public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5131572abd..3099c6984c 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -123,9 +123,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); - - foreach (var mapping in HitObject.ProgressionSamples) - mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -223,22 +220,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables UpdateJudgement(true); - if (AllJudged) - return true; - - // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects - // This causes the playfield to not play sounds, so they need to be handled locally - - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = HitObject.ProgressionSamples[mappingIndex]; - if (isCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 7976cbbbc1..cf0df260b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,6 +6,10 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; +using System; +using System.Linq; +using osu.Game.Audio; +using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -35,6 +39,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.KiaiMode = HitObject.Kiai; } + // Normal and clap samples are handled by the drum + protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP); + protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); public abstract bool OnPressed(TaikoAction action); diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 714e5d29ee..95ea9f8aa4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -20,18 +20,5 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; - - public List ProgressionSamples = new List(); - - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - - var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } - .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); - - foreach (var point in progressionSamplePoints) - ProgressionSamples.Add(new DrumSampleMapping(point)); - } } } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 5e79166bec..8c02b21733 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,14 +2,20 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using System.Linq; using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -18,16 +24,26 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class InputDrum : Container { - public InputDrum() + private const float middle_split = 0.025f; + + private readonly ControlPointInfo controlPoints; + + public InputDrum(ControlPointInfo controlPoints) { + this.controlPoints = controlPoints; + RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; + } - const float middle_split = 0.025f; + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + var sampleMappings = new DrumSampleMapping(controlPoints, audio); Children = new Drawable[] { - new TaikoHalfDrum(false) + new TaikoHalfDrum(false, sampleMappings) { Name = "Left Half", Anchor = Anchor.Centre, @@ -38,7 +54,7 @@ namespace osu.Game.Rulesets.Taiko.UI RimAction = TaikoAction.LeftRim, CentreAction = TaikoAction.LeftCentre }, - new TaikoHalfDrum(true) + new TaikoHalfDrum(true, sampleMappings) { Name = "Right Half", Anchor = Anchor.Centre, @@ -72,8 +88,12 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Sprite centre; private readonly Sprite centreHit; - public TaikoHalfDrum(bool flipped) + private readonly DrumSampleMapping sampleMappings; + + public TaikoHalfDrum(bool flipped, DrumSampleMapping sampleMappings) { + this.sampleMappings = sampleMappings; + Masking = true; Children = new Drawable[] @@ -128,15 +148,21 @@ namespace osu.Game.Rulesets.Taiko.UI Drawable target = null; Drawable back = null; + var drumSample = sampleMappings.SampleAt(Time.Current); + if (action == CentreAction) { target = centreHit; back = centre; + + drumSample.Centre.Play(); } else if (action == RimAction) { target = rimHit; back = rim; + + drumSample.Rim.Play(); } if (target != null) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 229e44cf27..14f8de0f48 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -24,7 +24,7 @@ using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield, IKeyBindingHandler + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -59,13 +59,9 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box overlayBackground; private readonly Box background; - private readonly ControlPointInfo controlPointInfo; - private readonly List drumSampleMappings = new List(); - - public TaikoPlayfield(ControlPointInfo controlPointInfo) + public TaikoPlayfield(ControlPointInfo controlPoints) : base(Axes.X) { - this.controlPointInfo = controlPointInfo; AddRangeInternal(new Drawable[] { backgroundContainer = new Container @@ -158,7 +154,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - new InputDrum + new InputDrum(controlPoints) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -205,17 +201,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - // We may have 0 sample points, but we need at least the default one - var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } - .Concat(controlPointInfo.SamplePoints); - foreach (var s in samplePoints) - { - var mapping = new DrumSampleMapping(s); - mapping.RetrieveChannels(audio); - - drumSampleMappings.Add(mapping); - } overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1; @@ -281,23 +267,5 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); } } - - public bool OnPressed(TaikoAction action) - { - var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = drumSampleMappings[mappingIndex]; - - if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - - return true; - } - - public bool OnReleased(TaikoAction action) => false; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index be161b9ad3..ab4c04be3f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -72,6 +72,7 @@ namespace osu.Game.Rulesets.Objects.Drawables public IReadOnlyList Judgements => judgements; protected List Samples = new List(); + protected virtual IEnumerable GetSamples() => HitObject.Samples; public readonly Bindable State = new Bindable(); @@ -84,13 +85,14 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (Samples.Count > 0) + var samples = GetSamples(); + if (samples.Any()) { if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - foreach (SampleInfo s in HitObject.Samples) + foreach (SampleInfo s in samples) { SampleInfo localSampleInfo = new SampleInfo { From 35d7fa8a81ae017f964c1644ddac3db0b7f94135 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:38 +0900 Subject: [PATCH 10/10] Cleanup things that are now not needed with these changes --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 2 +- .../Objects/Drawables/DrawableHitStrong.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 4 +--- .../Objects/Drawables/DrawableTaikoHitObject.cs | 1 - osu.Game.Rulesets.Taiko/Objects/Swell.cs | 5 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 3 --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +------- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index df33aae94e..fd35f0eaec 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables validKeyPressed = HitActions.Contains(action); // Only count this as handled if the new judgement is a hit - return UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return UpdateJudgement(true); } protected override void Update() diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 07f7b83cef..cda82afe0e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return false; // Assume the intention was to hit the strong hit with both keys only if the first key is still being held down - return firstKeyHeld && UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return firstKeyHeld && UpdateJudgement(true); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 3099c6984c..5ca33aaea2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,8 +14,6 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; -using osu.Framework.Audio; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -118,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index cf0df260b1..92da3fe09e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,7 +6,6 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; -using System; using System.Linq; using osu.Game.Audio; using System.Collections.Generic; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 95ea9f8aa4..cd2876ea2d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,12 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using System.Linq; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 8c02b21733..bf1274256b 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using System.Linq; using OpenTK; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -12,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; -using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Audio; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 14f8de0f48..3fdbd056ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -16,11 +16,7 @@ using osu.Framework.Extensions.Color4Extensions; using System.Linq; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables; -using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; -using osu.Framework.Audio; -using System.Collections.Generic; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -199,10 +195,8 @@ namespace osu.Game.Rulesets.Taiko.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { - - overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1;