1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 05:22:54 +08:00

Add time-based flourish support

This commit is contained in:
Dean Herbert 2023-06-30 18:43:37 +09:00
parent c72ebcfd53
commit 16f1a7694d

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Game.Audio;
using osu.Game.Rulesets.Taiko.Objects;
@ -18,12 +19,20 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
public partial class ArgonDrumSampleTriggerSource : DrumSampleTriggerSource
{
private readonly HitObjectContainer hitObjectContainer;
[Resolved]
private ISkinSource skinSource { get; set; } = null!;
/// <summary>
/// The minimum time to leave between flourishes that are added to strong rim hits.
/// </summary>
private const double time_between_flourishes = 2000;
public ArgonDrumSampleTriggerSource(HitObjectContainer hitObjectContainer, SampleBalance balance)
: base(hitObjectContainer, balance)
{
this.hitObjectContainer = hitObjectContainer;
// TODO: pool flourish sample
}
@ -44,21 +53,41 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
}
// let the magic begin...
var samplesToPlay = new List<ISampleInfo> { new VolumeAwareHitSampleInfo(originalSample, strong) };
if (strong)
if (strong && hitType == HitType.Rim && canPlayFlourish(hitObject))
samplesToPlay.Add(new VolumeAwareHitSampleInfo(hitObject.CreateHitSampleInfo(HitSampleInfo.HIT_FLOURISH), true));
PlaySamples(samplesToPlay.ToArray());
}
private bool canPlayFlourish(TaikoHitObject hitObject)
{
double? lastFlourish = null;
// TODO: check on nested strong hits. we're not accounting for them here yet.
var hitObjects = hitObjectContainer.AliveObjects
.Reverse()
.Select(d => d.HitObject)
.OfType<Hit>()
.Where(h => h.IsStrong && h.Type == HitType.Rim);
// Add an additional 'flourish' sample to strong rim hits (that are at least `time_between_flourishes` apart).
// This is applied to hitobjects in reverse order, as to sound more musically coherent by biasing towards to
// end of groups/combos of strong rim hits instead of the start.
foreach (var h in hitObjects)
{
PlaySamples(new ISampleInfo[]
{
new VolumeAwareHitSampleInfo(originalSample, true),
// TODO: flourish should only play every time_between_flourishes.
new VolumeAwareHitSampleInfo(hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_FLOURISH : string.Empty), true),
new VolumeAwareHitSampleInfo(originalSample)
});
}
else
{
PlaySamples(new ISampleInfo[] { new VolumeAwareHitSampleInfo(new VolumeAwareHitSampleInfo(originalSample)) });
bool canFlourish = lastFlourish == null || lastFlourish - h.StartTime >= time_between_flourishes;
if (canFlourish)
lastFlourish = h.StartTime;
if (h == hitObject)
return canFlourish;
}
return false;
}
private class VolumeAwareHitSampleInfo : HitSampleInfo