diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
index bf9f0bd44b..4de8cd897f 100644
--- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
@@ -12,6 +12,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using OpenTK;
using osu.Framework.Lists;
+using osu.Framework.Extensions.IEnumerableExtensions;
namespace osu.Game.Rulesets.Catch.Objects
{
@@ -29,9 +30,14 @@ namespace osu.Game.Rulesets.Catch.Objects
public double Velocity;
public double TickDistance;
+ private ControlPointInfo controlPointInfo;
+ private BeatmapDifficulty difficulty;
+
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaults(controlPointInfo, difficulty);
+ this.controlPointInfo = controlPointInfo;
+ this.difficulty = difficulty;
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
@@ -124,6 +130,8 @@ namespace osu.Game.Rulesets.Catch.Objects
});
}
+ ticks.ForEach(t => t.ApplyDefaults(controlPointInfo, difficulty));
+
return ticks;
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index fc1331551e..2b68dcf62c 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -63,10 +63,16 @@ namespace osu.Game.Rulesets.Mania.Objects
///
private double tickSpacing = 50;
+ private ControlPointInfo controlPointInfo;
+ private BeatmapDifficulty difficulty;
+
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaults(controlPointInfo, difficulty);
+ this.controlPointInfo = controlPointInfo;
+ this.difficulty = difficulty;
+
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
tickSpacing = timingPoint.BeatLength / difficulty.SliderTickRate;
@@ -89,11 +95,15 @@ namespace osu.Game.Rulesets.Mania.Objects
for (double t = StartTime + tickSpacing; t <= EndTime - tickSpacing; t += tickSpacing)
{
- ret.Add(new HoldNoteTick
+ var tick = new HoldNoteTick
{
StartTime = t,
Column = Column
- });
+ };
+
+ tick.ApplyDefaults(controlPointInfo, difficulty);
+
+ ret.Add(tick);
}
return ret;
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 42f54af801..a91d846aa7 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -57,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Scale = s.Scale,
ComboColour = s.ComboColour,
Samples = s.Samples,
+ SoundControlPoint = s.SoundControlPoint
})
};
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 39ec753fe1..ec1b146328 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -10,6 +10,7 @@ using System.Linq;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
+using osu.Framework.Extensions.IEnumerableExtensions;
namespace osu.Game.Rulesets.Osu.Objects
{
@@ -74,10 +75,16 @@ namespace osu.Game.Rulesets.Osu.Objects
public double Velocity;
public double TickDistance;
+ private ControlPointInfo controlPointInfo;
+ private BeatmapDifficulty difficulty;
+
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaults(controlPointInfo, difficulty);
+ this.controlPointInfo = controlPointInfo;
+ this.difficulty = difficulty;
+
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
@@ -124,7 +131,7 @@ namespace osu.Game.Rulesets.Osu.Objects
var distanceProgress = d / length;
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
- yield return new SliderTick
+ var ret = new SliderTick
{
RepeatIndex = repeat,
StartTime = repeatStartTime + timeProgress * repeatDuration,
@@ -139,6 +146,10 @@ namespace osu.Game.Rulesets.Osu.Objects
Volume = s.Volume
}))
};
+
+ ret.ApplyDefaults(controlPointInfo, difficulty);
+
+ yield return ret;
}
}
}
@@ -158,7 +169,7 @@ namespace osu.Game.Rulesets.Osu.Objects
var repeatStartTime = StartTime + repeat * repeatDuration;
var distanceProgress = d / length;
- yield return new RepeatPoint
+ var ret = new RepeatPoint
{
RepeatIndex = repeat,
StartTime = repeatStartTime,
@@ -167,6 +178,10 @@ namespace osu.Game.Rulesets.Osu.Objects
Scale = Scale,
ComboColour = ComboColour,
};
+
+ ret.ApplyDefaults(controlPointInfo, difficulty);
+
+ yield return ret;
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index 526d23f51a..a2503b8060 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -55,9 +55,14 @@ namespace osu.Game.Rulesets.Taiko.Objects
///
private double tickSpacing = 100;
+ private ControlPointInfo controlPointInfo;
+ private BeatmapDifficulty difficulty;
+
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaults(controlPointInfo, difficulty);
+ this.controlPointInfo = controlPointInfo;
+ this.difficulty = difficulty;
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
@@ -77,7 +82,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
bool first = true;
for (double t = StartTime; t < EndTime + tickSpacing / 2; t += tickSpacing)
{
- ret.Add(new DrumRollTick
+ var tick = new DrumRollTick
{
FirstTick = first,
TickSpacing = tickSpacing,
@@ -89,12 +94,15 @@ namespace osu.Game.Rulesets.Taiko.Objects
Name = @"slidertick",
Volume = s.Volume
}))
- });
+ };
+ tick.ApplyDefaults(controlPointInfo, difficulty);
+
+ ret.Add(tick);
first = false;
}
return ret;
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs
index 3c3a64dbb2..2cde4e01ad 100644
--- a/osu.Game/Audio/SampleInfo.cs
+++ b/osu.Game/Audio/SampleInfo.cs
@@ -15,40 +15,19 @@ namespace osu.Game.Audio
public const string HIT_NORMAL = @"hitnormal";
public const string HIT_CLAP = @"hitclap";
- ///
- /// The that is used for and
- /// if the values have not already been provided by the hitobject.
- ///
- [JsonIgnore]
- public SoundControlPoint ControlPoint;
-
- private string bank;
///
/// The bank to load the sample from.
///
- public string Bank
- {
- get { return string.IsNullOrEmpty(bank) ? (ControlPoint?.SampleBank ?? "normal") : bank; }
- set { bank = value; }
- }
-
- public bool ShouldSerializeBank() => Bank != ControlPoint.SampleBank;
+ public string Bank;
///
/// The name of the sample to load.
///
- public string Name { get; set; }
+ public string Name;
- private int volume;
///
/// The sample volume.
///
- public int Volume
- {
- get { return volume == 0 ? (ControlPoint?.SampleVolume ?? 0) : volume; }
- set { volume = value; }
- }
-
- public bool ShouldSerializeVolume() => Volume != ControlPoint.SampleVolume;
+ public int Volume;
}
}
diff --git a/osu.Game/Beatmaps/ControlPoints/SoundControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SoundControlPoint.cs
index 8084229382..b73a03b95a 100644
--- a/osu.Game/Beatmaps/ControlPoints/SoundControlPoint.cs
+++ b/osu.Game/Beatmaps/ControlPoints/SoundControlPoint.cs
@@ -5,14 +5,16 @@ namespace osu.Game.Beatmaps.ControlPoints
{
public class SoundControlPoint : ControlPoint
{
+ public const string DEFAULT_BANK = "normal";
+
///
/// The default sample bank at this control point.
///
- public string SampleBank;
+ public string SampleBank = DEFAULT_BANK;
///
/// The default sample volume at this control point.
///
public int SampleVolume;
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index 57db36fda5..4f5f8898f8 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -86,12 +86,23 @@ namespace osu.Game.Rulesets.Objects.Drawables
{
foreach (SampleInfo sample in HitObject.Samples)
{
- SampleChannel channel = audio.Sample.Get($@"Gameplay/{sample.Bank}-{sample.Name}");
+ if (HitObject.SoundControlPoint == null)
+ throw new ArgumentNullException(nameof(HitObject.SoundControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SoundControlPoint)}.");
+
+ var bank = sample.Bank;
+ if (string.IsNullOrEmpty(bank))
+ bank = HitObject.SoundControlPoint.SampleBank;
+
+ int volume = sample.Volume;
+ if (volume == 0)
+ volume = HitObject.SoundControlPoint.SampleVolume;
+
+ SampleChannel channel = audio.Sample.Get($@"Gameplay/{bank}-{sample.Name}");
if (channel == null)
continue;
- channel.Volume.Value = sample.Volume;
+ channel.Volume.Value = volume;
Samples.Add(channel);
}
}
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index 0772e7707e..66e34eac32 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -31,6 +31,9 @@ namespace osu.Game.Rulesets.Objects
///
public SampleInfoList Samples = new SampleInfoList();
+ [JsonIgnore]
+ public SoundControlPoint SoundControlPoint;
+
///
/// Whether this is in Kiai time.
///
@@ -48,13 +51,7 @@ namespace osu.Game.Rulesets.Objects
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
Kiai = effectPoint.KiaiMode;
-
- // Initialize first sample
- Samples.ForEach(s => s.ControlPoint = soundPoint);
-
- // Initialize any repeat samples
- var repeatData = this as IHasRepeats;
- repeatData?.RepeatSamples?.ForEach(r => r.ForEach(s => s.ControlPoint = soundPoint));
+ SoundControlPoint = soundPoint;
}
}
}