diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs index fec675be54..3e8d022af2 100644 --- a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -43,7 +43,7 @@ namespace osu.Game.Modes.Osu.Beatmaps return new Slider { StartTime = original.StartTime, - Sample = original.Sample, + SampleBank = original.SampleBank, CurveObject = curveData, Position = positionData?.Position ?? Vector2.Zero, NewCombo = comboData?.NewCombo ?? false @@ -55,7 +55,7 @@ namespace osu.Game.Modes.Osu.Beatmaps return new Spinner { StartTime = original.StartTime, - Sample = original.Sample, + SampleBank = original.SampleBank, Position = new Vector2(512, 384) / 2, EndTime = endTimeData.EndTime }; @@ -64,7 +64,7 @@ namespace osu.Game.Modes.Osu.Beatmaps return new HitCircle { StartTime = original.StartTime, - Sample = original.Sample, + SampleBank = original.SampleBank, Position = positionData?.Position ?? Vector2.Zero, NewCombo = comboData?.NewCombo ?? false }; diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs index e8f2154d7f..cd8086720f 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs @@ -67,7 +67,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables ComboIndex = s.ComboIndex, Scale = s.Scale, ComboColour = s.ComboColour, - Sample = s.Sample, + SampleBank = s.SampleBank, }), }; @@ -111,7 +111,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables if (repeat > currentRepeat) { if (repeat < slider.RepeatCount && ball.Tracking) - PlaySample(); + PlaySamples(); currentRepeat = repeat; } diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs index be66689054..1bcfb54b24 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -58,12 +58,10 @@ namespace osu.Game.Modes.Osu.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - string sampleSet = (HitObject.Sample?.Set ?? SampleSet.Normal).ToString().ToLower(); - - sample = audio.Sample.Get($@"Gameplay/{sampleSet}-slidertick"); + sample = audio.Sample.Get($@"Gameplay/{HitObject.SampleBank.Name.ToLower()}-slidertick"); } - protected override void PlaySample() + protected override void PlaySamples() { sample?.Play(); } diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index 38d1dfda5d..0fa837207f 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -95,11 +95,7 @@ namespace osu.Game.Modes.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Sample = new HitSampleInfo - { - Type = SampleType.None, - Set = SampleSet.Soft, - }, + SampleBank = SampleBank }; } } diff --git a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 594ed5f309..903ac5ae05 100644 --- a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -57,9 +57,9 @@ namespace osu.Game.Modes.Taiko.Beatmaps var endTimeData = obj as IHasEndTime; // Old osu! used hit sounding to determine various hit type information - SampleType sample = obj.Sample?.Type ?? SampleType.None; + SampleBank sampleBank = obj.SampleBank; - bool strong = (sample & SampleType.Finish) > 0; + bool strong = sampleBank.Sets.Any(s => s.Type == SampleType.Finish); if (distanceData != null) { @@ -98,7 +98,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new CentreHit { StartTime = j, - Sample = obj.Sample, + SampleBank = obj.SampleBank, IsStrong = strong, VelocityMultiplier = legacy_velocity_multiplier }; @@ -109,7 +109,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new DrumRoll { StartTime = obj.StartTime, - Sample = obj.Sample, + SampleBank = obj.SampleBank, IsStrong = strong, Distance = distance, TickRate = beatmap.BeatmapInfo.Difficulty.SliderTickRate == 3 ? 3 : 4, @@ -124,7 +124,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new Swell { StartTime = obj.StartTime, - Sample = obj.Sample, + SampleBank = obj.SampleBank, IsStrong = strong, EndTime = endTimeData.EndTime, RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier), @@ -133,14 +133,14 @@ namespace osu.Game.Modes.Taiko.Beatmaps } else { - bool isCentre = (sample & ~(SampleType.Finish | SampleType.Normal)) == 0; + bool isCentre = sampleBank.Sets.Any(s => s.Type == SampleType.Normal); if (isCentre) { yield return new CentreHit { StartTime = obj.StartTime, - Sample = obj.Sample, + SampleBank = obj.SampleBank, IsStrong = strong, VelocityMultiplier = legacy_velocity_multiplier }; @@ -150,7 +150,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new RimHit { StartTime = obj.StartTime, - Sample = obj.Sample, + SampleBank = obj.SampleBank, IsStrong = strong, VelocityMultiplier = legacy_velocity_multiplier }; diff --git a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs b/osu.Game.Modes.Taiko/Objects/DrumRoll.cs index ede576835c..427ddcf3fa 100644 --- a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Modes.Taiko/Objects/DrumRoll.cs @@ -95,11 +95,7 @@ namespace osu.Game.Modes.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - Sample = new HitSampleInfo - { - Type = SampleType.None, - Set = SampleSet.Soft - } + SampleBank = SampleBank }); first = false; diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs index 3c1f4eaf45..cc3d507038 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs @@ -136,12 +136,12 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(slider); Assert.AreEqual(new Vector2(192, 168), slider.Position); Assert.AreEqual(956, slider.StartTime); - Assert.AreEqual(SampleType.None, slider.Sample.Type); + Assert.AreEqual(SampleType.None, slider.SampleBank.Type); var hit = beatmap.HitObjects[1] as LegacyHit; Assert.IsNotNull(hit); Assert.AreEqual(new Vector2(304, 56), hit.Position); Assert.AreEqual(1285, hit.StartTime); - Assert.AreEqual(SampleType.Clap, hit.Sample.Type); + Assert.AreEqual(SampleType.Clap, hit.SampleBank.Type); } } } diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index c1b802bb48..7c042b4907 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -31,7 +31,7 @@ namespace osu.Game.Beatmaps.Formats // TODO: Not sure how far back to go, or differences between versions } - private SampleSet defaultSampleSet; + private Sample defaultSampleSet; private int defaultSampleVolume = 100; private bool samplesMatchPlaybackRate; @@ -77,7 +77,7 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.Countdown = int.Parse(val) == 1; break; case @"SampleSet": - defaultSampleSet = (SampleSet)Enum.Parse(typeof(SampleSet), val); + defaultSampleSet = (Sample)Enum.Parse(typeof(Sample), val); break; case @"SampleVolume": defaultSampleVolume = int.Parse(val); @@ -222,9 +222,9 @@ namespace osu.Game.Beatmaps.Formats if (split.Length >= 3) timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)int.Parse(split[2]); - SampleSet sampleSet = defaultSampleSet; + Sample sampleSet = defaultSampleSet; if (split.Length >= 4) - sampleSet = (SampleSet)int.Parse(split[3]); + sampleSet = (Sample)int.Parse(split[3]); SampleBank sampleBank = SampleBank.Default; if (split.Length >= 5) diff --git a/osu.Game/Beatmaps/Samples/HitSampleInfo.cs b/osu.Game/Beatmaps/Samples/HitSampleInfo.cs deleted file mode 100644 index f5a5cc1bea..0000000000 --- a/osu.Game/Beatmaps/Samples/HitSampleInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Beatmaps.Samples -{ - public class HitSampleInfo : SampleInfo - { - public SampleType Type; - } -} diff --git a/osu.Game/Beatmaps/Samples/Sample.cs b/osu.Game/Beatmaps/Samples/Sample.cs new file mode 100644 index 0000000000..d90362bd0b --- /dev/null +++ b/osu.Game/Beatmaps/Samples/Sample.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Beatmaps.Samples +{ + /// + /// A defines a type of sound that is to be played. + /// + public class Sample + { + /// + /// The type of sound to be played. + /// + public SampleType Type; + + /// + /// The volume to be played at. + /// + public int? Volume; + } +} diff --git a/osu.Game/Beatmaps/Samples/SampleBank.cs b/osu.Game/Beatmaps/Samples/SampleBank.cs index 2154713cff..30876c2ce0 100644 --- a/osu.Game/Beatmaps/Samples/SampleBank.cs +++ b/osu.Game/Beatmaps/Samples/SampleBank.cs @@ -1,12 +1,29 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// 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.Beatmaps.Samples { - public enum SampleBank + /// + /// Wraps a list of to change which bank of files are used for each . + /// + public class SampleBank { - Default = 0, - Custom1 = 1, - Custom2 = 2 + /// + /// The list of samples that are to be played to be played from this bank. + /// + public List Sets; + + /// + /// In conversion from osu-stable, this is equivalent to SampleSet (_not_ CustomSampleSet). + /// i.e. None/Normal/Soft/Drum + /// + public string Name; + + /// + /// Default sample volume. + /// + public int Volume; } -} \ No newline at end of file +} diff --git a/osu.Game/Beatmaps/Samples/SampleInfo.cs b/osu.Game/Beatmaps/Samples/SampleInfo.cs deleted file mode 100644 index 5b8f44d116..0000000000 --- a/osu.Game/Beatmaps/Samples/SampleInfo.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Beatmaps.Samples -{ - public class SampleInfo - { - public SampleBank Bank; - public SampleSet Set; - public int Volume; - } -} diff --git a/osu.Game/Beatmaps/Samples/SampleSet.cs b/osu.Game/Beatmaps/Samples/SampleSet.cs deleted file mode 100644 index 72f97d9e0e..0000000000 --- a/osu.Game/Beatmaps/Samples/SampleSet.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Beatmaps.Samples -{ - public enum SampleSet - { - None = 0, - Normal = 1, - Soft = 2, - Drum = 3 - } -} \ No newline at end of file diff --git a/osu.Game/Beatmaps/Samples/SampleType.cs b/osu.Game/Beatmaps/Samples/SampleType.cs index 0a18a65201..ea2fc96810 100644 --- a/osu.Game/Beatmaps/Samples/SampleType.cs +++ b/osu.Game/Beatmaps/Samples/SampleType.cs @@ -1,17 +1,14 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; - namespace osu.Game.Beatmaps.Samples { - [Flags] public enum SampleType { - None = 0, - Normal = 1, - Whistle = 2, - Finish = 4, - Clap = 8 - }; -} \ No newline at end of file + None, + Normal, + Whistle, + Finish, + Clap + } +} diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index ed8269876e..352c660d4c 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -15,7 +15,7 @@ using OpenTK.Graphics; namespace osu.Game.Modes.Objects.Drawables { - public abstract class DrawableHitObject : Container, IStateful + public abstract class DrawableHitObject : Container where TJudgement : Judgement { public override bool HandleInput => Interactive; @@ -24,9 +24,44 @@ namespace osu.Game.Modes.Objects.Drawables public TJudgement Judgement; - protected abstract TJudgement CreateJudgement(); + protected override void LoadComplete() + { + base.LoadComplete(); - protected abstract void UpdateState(ArmedState state); + // We may be setting a custom judgement in test cases or what not + if (Judgement == null) + Judgement = CreateJudgement(); + } + + protected abstract TJudgement CreateJudgement(); + } + + public abstract class DrawableHitObject : DrawableHitObject, IStateful + where TObject : HitObject + where TJudgement : Judgement + { + public event Action> OnJudgement; + + /// + /// The colour used for various elements of this DrawableHitObject. + /// + public Color4 AccentColour { get; protected set; } + + public TObject HitObject; + + private readonly List samples = new List(); + + protected DrawableHitObject(TObject hitObject) + { + HitObject = hitObject; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + foreach (var sample in HitObject.SampleBank.Sets) + samples.Add(audio.Sample.Get($@"Gameplay/{sample.Type.ToString().ToLower()}-hit{HitObject.SampleBank.Name.ToLower()}")); + } private ArmedState state; public ArmedState State @@ -45,47 +80,17 @@ namespace osu.Game.Modes.Objects.Drawables UpdateState(state); if (State == ArmedState.Hit) - PlaySample(); + PlaySamples(); } } - protected SampleChannel Sample; - - protected virtual void PlaySample() - { - Sample?.Play(); - } - protected override void LoadComplete() { base.LoadComplete(); - //we may be setting a custom judgement in test cases or what not. - if (Judgement == null) - Judgement = CreateJudgement(); - - //force application of the state that was set before we loaded. + // Force application of the state that was set before we loaded UpdateState(State); } - } - - public abstract class DrawableHitObject : DrawableHitObject - where TObject : HitObject - where TJudgement : Judgement - { - public event Action> OnJudgement; - - public TObject HitObject; - - /// - /// The colour used for various elements of this DrawableHitObject. - /// - public Color4 AccentColour { get; protected set; } - - protected DrawableHitObject(TObject hitObject) - { - HitObject = hitObject; - } /// /// Process a hit of this hitobject. Carries out judgement. @@ -149,16 +154,9 @@ namespace osu.Game.Modes.Objects.Drawables UpdateJudgement(false); } - [BackgroundDependencyLoader] - private void load(AudioManager audio) + protected virtual void PlaySamples() { - SampleType type = HitObject.Sample?.Type ?? SampleType.None; - if (type == SampleType.None) - type = SampleType.Normal; - - SampleSet sampleSet = HitObject.Sample?.Set ?? SampleSet.Normal; - - Sample = audio.Sample.Get($@"Gameplay/{sampleSet.ToString().ToLower()}-hit{type.ToString().ToLower()}"); + samples.ForEach(s => s?.Play()); } private List> nestedHitObjects; @@ -173,5 +171,7 @@ namespace osu.Game.Modes.Objects.Drawables h.OnJudgement += d => OnJudgement?.Invoke(d); nestedHitObjects.Add(h); } + + protected abstract void UpdateState(ArmedState state); } } diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index f2712d92ba..d734dce073 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -21,9 +21,9 @@ namespace osu.Game.Modes.Objects public double StartTime { get; set; } /// - /// The sample to be played when this HitObject is hit. + /// The sample bank to be played when this hit object is hit. /// - public HitSampleInfo Sample { get; set; } + public SampleBank SampleBank { get; set; } /// /// Applies default values to this HitObject. diff --git a/osu.Game/Modes/Objects/LegacyHitObjectParser.cs b/osu.Game/Modes/Objects/LegacyHitObjectParser.cs index ccc5f18822..bb94d02d38 100644 --- a/osu.Game/Modes/Objects/LegacyHitObjectParser.cs +++ b/osu.Game/Modes/Objects/LegacyHitObjectParser.cs @@ -105,10 +105,10 @@ namespace osu.Game.Modes.Objects throw new InvalidOperationException($@"Unknown hit object type {type}"); result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture); - result.Sample = new HitSampleInfo + result.SampleBank = new HitSampleInfo { Type = (SampleType)int.Parse(split[4]), - Set = SampleSet.Soft, + Set = Sample.Soft, }; // TODO: "addition" field diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index da3b4dd406..c8a38bc48e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -76,6 +76,9 @@ + + + @@ -148,11 +151,6 @@ - - - - -