diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs index 3e8d022af2..e0cd66ca94 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, - SampleBank = original.SampleBank, + SampleBanks = original.SampleBanks, 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, - SampleBank = original.SampleBank, + SampleBanks = original.SampleBanks, 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, - SampleBank = original.SampleBank, + SampleBanks = original.SampleBanks, 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 cd8086720f..596bd2cb9d 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, - SampleBank = s.SampleBank, + SampleBanks = s.SampleBanks, }), }; diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs index 47eecccf66..c8fd60c8d6 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -12,6 +12,7 @@ using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Judgements; using OpenTK; using OpenTK.Graphics; +using System.Collections.Generic; namespace osu.Game.Modes.Osu.Objects.Drawables { @@ -28,6 +29,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.SliderTick }; + private List samples = new List(); + public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick) { this.sliderTick = sliderTick; @@ -53,20 +56,18 @@ namespace osu.Game.Modes.Osu.Objects.Drawables }; } - private SampleChannel sample; - [BackgroundDependencyLoader] private void load(AudioManager audio) { - sample = audio.Sample.Get($@"Gameplay/{HitObject.SampleBank.Name}-slidertick"); + foreach (var bank in HitObject.SampleBanks) + samples.Add(audio.Sample.Get($@"Gameplay/{bank.Name}-slidertick")); } protected override void PlaySamples() { - sample?.Play(); + samples.ForEach(s => s?.Play()); } - protected override void CheckJudgement(bool userTriggered) { if (Judgement.TimeOffset >= 0) diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index 0fa837207f..49d16ec859 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -95,7 +95,7 @@ namespace osu.Game.Modes.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - SampleBank = SampleBank + SampleBanks = SampleBanks }; } } diff --git a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 903ac5ae05..d0dce85863 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 - SampleBank sampleBank = obj.SampleBank; + List sampleBanks = obj.SampleBanks; - bool strong = sampleBank.Sets.Any(s => s.Type == SampleType.Finish); + bool strong = sampleBanks.Any(b => b.Samples.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, - SampleBank = obj.SampleBank, + SampleBanks = obj.SampleBanks, IsStrong = strong, VelocityMultiplier = legacy_velocity_multiplier }; @@ -109,7 +109,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new DrumRoll { StartTime = obj.StartTime, - SampleBank = obj.SampleBank, + SampleBanks = obj.SampleBanks, 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, - SampleBank = obj.SampleBank, + SampleBanks = obj.SampleBanks, 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 = sampleBank.Sets.Any(s => s.Type == SampleType.Normal); + bool isCentre = sampleBanks.Any(b => b.Samples.Any(s => s.Type == SampleType.Normal)); if (isCentre) { yield return new CentreHit { StartTime = obj.StartTime, - SampleBank = obj.SampleBank, + SampleBanks = obj.SampleBanks, IsStrong = strong, VelocityMultiplier = legacy_velocity_multiplier }; @@ -150,7 +150,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps yield return new RimHit { StartTime = obj.StartTime, - SampleBank = obj.SampleBank, + SampleBanks = obj.SampleBanks, 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 427ddcf3fa..52878fa688 100644 --- a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Modes.Taiko/Objects/DrumRoll.cs @@ -95,7 +95,7 @@ namespace osu.Game.Modes.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - SampleBank = SampleBank + SampleBanks = SampleBanks }); first = false; diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs index cc3d507038..27ff942aa7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs @@ -11,6 +11,7 @@ using osu.Game.Modes; using osu.Game.Tests.Resources; using osu.Game.Modes.Osu; using osu.Game.Modes.Objects.Legacy; +using System.Linq; namespace osu.Game.Tests.Beatmaps.Formats { @@ -136,12 +137,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.SampleBank.Type); + Assert.IsTrue(slider.SampleBanks.Any(b => b.Name == "none")); 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.SampleBank.Type); + Assert.IsTrue(hit.SampleBanks.Any(b => b.Name == "clap")); } } } diff --git a/osu.Game/Beatmaps/Samples/SampleBank.cs b/osu.Game/Beatmaps/Samples/SampleBank.cs index 30876c2ce0..7ec81e64fa 100644 --- a/osu.Game/Beatmaps/Samples/SampleBank.cs +++ b/osu.Game/Beatmaps/Samples/SampleBank.cs @@ -13,7 +13,7 @@ namespace osu.Game.Beatmaps.Samples /// /// The list of samples that are to be played to be played from this bank. /// - public List Sets; + public List Samples; /// /// In conversion from osu-stable, this is equivalent to SampleSet (_not_ CustomSampleSet). diff --git a/osu.Game/Beatmaps/Timing/ControlPoint.cs b/osu.Game/Beatmaps/Timing/ControlPoint.cs index 00d3acba71..eb965cf678 100644 --- a/osu.Game/Beatmaps/Timing/ControlPoint.cs +++ b/osu.Game/Beatmaps/Timing/ControlPoint.cs @@ -13,7 +13,7 @@ namespace osu.Game.Beatmaps.Timing TimingChange = true, }; - public SampleInfo Sample; + public SampleBank SampleBank; public TimeSignatures TimeSignature; public double Time; public double BeatLength; diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 29b0e00351..53eb890719 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -59,8 +59,9 @@ namespace osu.Game.Modes.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - foreach (var sample in HitObject.SampleBank.Sets) - samples.Add(audio.Sample.Get($@"Gameplay/{sample.Type}-hit{HitObject.SampleBank.Name}")); + foreach (var bank in HitObject.SampleBanks) + foreach (var sample in bank.Samples) + samples.Add(audio.Sample.Get($@"Gameplay/{sample.Type}-hit{bank.Name}")); } private ArmedState state; diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index d734dce073..7d91885dcb 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -4,6 +4,7 @@ using osu.Game.Beatmaps.Samples; using osu.Game.Beatmaps.Timing; using osu.Game.Database; +using System.Collections.Generic; namespace osu.Game.Modes.Objects { @@ -21,15 +22,29 @@ namespace osu.Game.Modes.Objects public double StartTime { get; set; } /// - /// The sample bank to be played when this hit object is hit. + /// The sample banks to be played when this hit object is hit. /// - public SampleBank SampleBank { get; set; } + public List SampleBanks = new List(); /// /// Applies default values to this HitObject. /// /// The difficulty settings to use. /// The timing settings to use. - public virtual void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) { } + public virtual void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) + { + foreach (var bank in SampleBanks) + { + if (!string.IsNullOrEmpty(bank.Name)) + continue; + + // If the bank is not assigned a name, assign it from the relevant timing point + ControlPoint overridePoint; + ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint); + + bank.Name = (overridePoint ?? timingPoint)?.SampleBank.Name ?? string.Empty; + bank.Volume = (overridePoint ?? timingPoint)?.SampleBank.Volume ?? 0; + } + } } }