mirror of
https://github.com/ppy/osu
synced 2025-03-02 01:21:19 +00:00
Merge pull request #12340 from smoogipoo/add-slider-whistle
Add support for sliderwhistle
This commit is contained in:
commit
c0837b1c88
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osuTK;
|
||||
@ -108,16 +109,27 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
protected override void LoadSamples()
|
||||
{
|
||||
base.LoadSamples();
|
||||
// Note: base.LoadSamples() isn't called since the slider plays the tail's hitsounds for the time being.
|
||||
|
||||
var firstSample = HitObject.Samples.FirstOrDefault();
|
||||
|
||||
if (firstSample != null)
|
||||
if (HitObject.SampleControlPoint == null)
|
||||
{
|
||||
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample).With("sliderslide");
|
||||
|
||||
slidingSample.Samples = new ISampleInfo[] { clone };
|
||||
throw new InvalidOperationException($"{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}.");
|
||||
}
|
||||
|
||||
Samples.Samples = HitObject.TailSamples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast<ISampleInfo>().ToArray();
|
||||
|
||||
var slidingSamples = new List<ISampleInfo>();
|
||||
|
||||
var normalSample = HitObject.Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL);
|
||||
if (normalSample != null)
|
||||
slidingSamples.Add(HitObject.SampleControlPoint.ApplyTo(normalSample).With("sliderslide"));
|
||||
|
||||
var whistleSample = HitObject.Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_WHISTLE);
|
||||
if (whistleSample != null)
|
||||
slidingSamples.Add(HitObject.SampleControlPoint.ApplyTo(whistleSample).With("sliderwhistle"));
|
||||
|
||||
slidingSample.Samples = slidingSamples.ToArray();
|
||||
}
|
||||
|
||||
public override void StopAllSamples()
|
||||
|
@ -81,6 +81,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
public List<IList<HitSampleInfo>> NodeSamples { get; set; } = new List<IList<HitSampleInfo>>();
|
||||
|
||||
[JsonIgnore]
|
||||
public IList<HitSampleInfo> TailSamples { get; private set; }
|
||||
|
||||
private int repeatCount;
|
||||
|
||||
public int RepeatCount
|
||||
@ -143,11 +146,6 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
Velocity = scoringDistance / timingPoint.BeatLength;
|
||||
TickDistance = scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier;
|
||||
|
||||
// The samples should be attached to the slider tail, however this can only be done after LegacyLastTick is removed otherwise they would play earlier than they're intended to.
|
||||
// For now, the samples are attached to and played by the slider itself at the correct end time.
|
||||
// ToArray call is required as GetNodeSamples may fallback to Samples itself (without it it will get cleared due to the list reference being live).
|
||||
Samples = this.GetNodeSamples(repeatCount + 1).ToArray();
|
||||
}
|
||||
|
||||
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
||||
@ -238,6 +236,10 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
if (HeadCircle != null)
|
||||
HeadCircle.Samples = this.GetNodeSamples(0);
|
||||
|
||||
// The samples should be attached to the slider tail, however this can only be done after LegacyLastTick is removed otherwise they would play earlier than they're intended to.
|
||||
// For now, the samples are played by the slider itself at the correct end time.
|
||||
TailSamples = this.GetNodeSamples(repeatCount + 1);
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => OnlyJudgeNestedObjects ? new OsuIgnoreJudgement() : new OsuJudgement();
|
||||
|
@ -273,7 +273,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
if (hitObject is IHasPath path)
|
||||
{
|
||||
addPathData(writer, path, position);
|
||||
writer.Write(getSampleBank(hitObject.Samples, zeroBanks: true));
|
||||
writer.Write(getSampleBank(hitObject.Samples));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -420,15 +420,15 @@ namespace osu.Game.Beatmaps.Formats
|
||||
writer.Write(FormattableString.Invariant($"{endTimeData.EndTime}{suffix}"));
|
||||
}
|
||||
|
||||
private string getSampleBank(IList<HitSampleInfo> samples, bool banksOnly = false, bool zeroBanks = false)
|
||||
private string getSampleBank(IList<HitSampleInfo> samples, bool banksOnly = false)
|
||||
{
|
||||
LegacySampleBank normalBank = toLegacySampleBank(samples.SingleOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)?.Bank);
|
||||
LegacySampleBank addBank = toLegacySampleBank(samples.FirstOrDefault(s => !string.IsNullOrEmpty(s.Name) && s.Name != HitSampleInfo.HIT_NORMAL)?.Bank);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(FormattableString.Invariant($"{(zeroBanks ? 0 : (int)normalBank)}:"));
|
||||
sb.Append(FormattableString.Invariant($"{(zeroBanks ? 0 : (int)addBank)}"));
|
||||
sb.Append(FormattableString.Invariant($"{(int)normalBank}:"));
|
||||
sb.Append(FormattableString.Invariant($"{(int)addBank}"));
|
||||
|
||||
if (!banksOnly)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user