Merge pull request #12340 from smoogipoo/add-slider-whistle

Add support for sliderwhistle
This commit is contained in:
Dean Herbert 2021-04-09 18:12:46 +09:00 committed by GitHub
commit c0837b1c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 16 deletions

View File

@ -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()

View File

@ -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();

View File

@ -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)
{