Skip to content

Commit

Permalink
Merge pull request #355 from LumpBloom7/improve-slide-conversion-rules
Browse files Browse the repository at this point in the history
Improve slide conversion rules
  • Loading branch information
LumpBloom7 authored Jul 23, 2022
2 parents ec7a151 + cb207d9 commit 06dc107
Showing 1 changed file with 54 additions and 25 deletions.
79 changes: 54 additions & 25 deletions osu.Game.Rulesets.Sentakki/Beatmaps/SentakkiBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,36 +155,20 @@ private IEnumerable<SentakkiHitObject> convertSlider(HitObject original)
twin = true;
}

// See if we can convert to a slide object
if (special && slider.Duration >= 350)
{
List<Slide> slides = new List<Slide>();
if (EnabledExperiments.HasFlag(ConversionExperiments.twinSlides))
var result = tryConvertSliderToSlide(original, nodeSamples, twin, breakNote).ToList();
if (result.Any())
{
if (twin)
slides.Add((Slide)createSlideNote(original, nodeSamples, true, breakNote));
else
foreach (var note in createTapsFromTicks(original, nodeSamples))
yield return note;
}

slides.Add((Slide)createSlideNote(original, nodeSamples, false, breakNote));

// Make sure duplicates are cleared
if (slides.Count == 2 && slides.First().Lane == slides.Last().Lane)
{
// Make sure that both slides patterns are unique
if (!slides.First().SlideInfoList.Exists(x => x.ID == slides.Last().SlideInfoList.First().ID))
slides.First().SlideInfoList.AddRange(slides.Last().SlideInfoList);
foreach (var ho in result)
yield return ho;

slides.Remove(slides.Last());
yield break;
}

foreach (var slide in slides)
yield return slide;

yield break;
}

// Fallback to hold notes
if (EnabledExperiments.HasFlag(ConversionExperiments.twinNotes))
if (twin)
yield return createHoldNote(original, nodeSamples, true, breakNote);
Expand All @@ -195,6 +179,51 @@ private IEnumerable<SentakkiHitObject> convertSlider(HitObject original)
yield return createHoldNote(original, nodeSamples, false, breakNote);
}

private IEnumerable<SentakkiHitObject> tryConvertSliderToSlide(HitObject original, IList<IList<HitSampleInfo>> nodeSamples, bool twin = false, bool isBreak = false)
{
List<Slide> slides = new List<Slide>();
List<Tap> taps = new List<Tap>();
if (EnabledExperiments.HasFlag(ConversionExperiments.twinSlides))
{
if (twin)
slides.Add((Slide)createSlideNote(original, nodeSamples, true, isBreak));
else
taps.AddRange(createTapsFromTicks(original, nodeSamples));
}

slides.Add((Slide)createSlideNote(original, nodeSamples, false, isBreak));

// If there is a SlideFan, we always prioritize that, and ignore the rest
foreach (var slide in slides)
if (slide.SlideInfoList[0].ID == SlidePaths.FANID)
{
yield return slide;
yield break;
}

// If both slides have the same start lane, we attempt to merge them
if (slides.Count == 2 && slides[0].Lane == slides[1].Lane)
{
bool isSamePattern = slides[0].SlideInfoList[0].ID == slides[1].SlideInfoList[0].ID;
bool isSameOrientation = slides[0].SlideInfoList[0].Mirrored == slides[1].SlideInfoList[0].Mirrored;

// We merge both slides only if they both have the same pattern AND orientation
if (!isSamePattern || !isSameOrientation)
slides[0].SlideInfoList.AddRange(slides[1].SlideInfoList);

slides.RemoveAt(1);
}

if (slides.Count > 0)
{
foreach (var slide in slides)
yield return slide;

foreach (var tap in taps)
yield return tap;
}
}

#endregion

#region SentakkiHitObject creation methods
Expand Down Expand Up @@ -260,7 +289,7 @@ private SentakkiHitObject createSlideNote(HitObject original, IList<IList<HitSam
IEnumerable<(SentakkiSlidePath, SentakkiSlidePath)> pathEnumerable = SlidePaths.VALIDPATHS.Where(p => ((IHasDuration)original).Duration >= p.Item1.MinDuration && ((IHasDuration)original).Duration <= p.Item1.MaxDuration);

if (!EnabledExperiments.HasFlag(ConversionExperiments.fanSlides))
pathEnumerable = pathEnumerable.Where(s => s != SlidePaths.VALIDPATHS.Last());
pathEnumerable = pathEnumerable.Where(s => s != SlidePaths.VALIDPATHS[^1]);

validPaths = pathEnumerable.ToList();
}
Expand All @@ -285,7 +314,7 @@ private SentakkiHitObject createSlideNote(HitObject original, IList<IList<HitSam
};
}

private IEnumerable<SentakkiHitObject> createTapsFromTicks(HitObject original, IList<IList<HitSampleInfo>> nodeSamples)
private IEnumerable<Tap> createTapsFromTicks(HitObject original, IList<IList<HitSampleInfo>> nodeSamples)
{
if (original is not IHasPathWithRepeats)
yield break;
Expand Down

0 comments on commit 06dc107

Please sign in to comment.