mirror of
https://github.com/osukey/osukey.git
synced 2025-08-08 00:53:56 +09:00
Merge pull request #12340 from smoogipoo/add-slider-whistle
Add support for sliderwhistle
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -108,16 +109,27 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
protected override void LoadSamples()
|
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 (HitObject.SampleControlPoint == null)
|
||||||
|
|
||||||
if (firstSample != null)
|
|
||||||
{
|
{
|
||||||
var clone = HitObject.SampleControlPoint.ApplyTo(firstSample).With("sliderslide");
|
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}.");
|
||||||
slidingSample.Samples = new ISampleInfo[] { clone };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
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>>();
|
public List<IList<HitSampleInfo>> NodeSamples { get; set; } = new List<IList<HitSampleInfo>>();
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public IList<HitSampleInfo> TailSamples { get; private set; }
|
||||||
|
|
||||||
private int repeatCount;
|
private int repeatCount;
|
||||||
|
|
||||||
public int RepeatCount
|
public int RepeatCount
|
||||||
@ -143,11 +146,6 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
Velocity = scoringDistance / timingPoint.BeatLength;
|
Velocity = scoringDistance / timingPoint.BeatLength;
|
||||||
TickDistance = scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier;
|
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)
|
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
||||||
@ -238,6 +236,10 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
if (HeadCircle != null)
|
if (HeadCircle != null)
|
||||||
HeadCircle.Samples = this.GetNodeSamples(0);
|
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();
|
public override Judgement CreateJudgement() => OnlyJudgeNestedObjects ? new OsuIgnoreJudgement() : new OsuJudgement();
|
||||||
|
@ -273,7 +273,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
if (hitObject is IHasPath path)
|
if (hitObject is IHasPath path)
|
||||||
{
|
{
|
||||||
addPathData(writer, path, position);
|
addPathData(writer, path, position);
|
||||||
writer.Write(getSampleBank(hitObject.Samples, zeroBanks: true));
|
writer.Write(getSampleBank(hitObject.Samples));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -420,15 +420,15 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
writer.Write(FormattableString.Invariant($"{endTimeData.EndTime}{suffix}"));
|
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 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);
|
LegacySampleBank addBank = toLegacySampleBank(samples.FirstOrDefault(s => !string.IsNullOrEmpty(s.Name) && s.Name != HitSampleInfo.HIT_NORMAL)?.Bank);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
sb.Append(FormattableString.Invariant($"{(zeroBanks ? 0 : (int)normalBank)}:"));
|
sb.Append(FormattableString.Invariant($"{(int)normalBank}:"));
|
||||||
sb.Append(FormattableString.Invariant($"{(zeroBanks ? 0 : (int)addBank)}"));
|
sb.Append(FormattableString.Invariant($"{(int)addBank}"));
|
||||||
|
|
||||||
if (!banksOnly)
|
if (!banksOnly)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user