Factor out palpable obejct enumeration logic

This commit is contained in:
ekrctb 2023-02-03 14:07:21 +09:00
parent f8a5ce0cd2
commit 491ba13b6f
3 changed files with 28 additions and 25 deletions

View File

@ -5,6 +5,7 @@
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Catch.Beatmaps namespace osu.Game.Rulesets.Catch.Beatmaps
{ {
@ -38,5 +39,25 @@ public override IEnumerable<BeatmapStatistic> GetStatistics()
} }
}; };
} }
/// <summary>
/// Enumerate all <see cref="PalpableCatchHitObject"/>s, sorted by their start times.
/// </summary>
/// <remarks>
/// If multiple objects have the same start time, the ordering is preserved (it is a stable sorting).
/// </remarks>
public static IEnumerable<PalpableCatchHitObject> GetPalpableObjects(IEnumerable<HitObject> hitObjects)
{
return hitObjects.SelectMany(selectPalpableObjects).OrderBy(h => h.StartTime);
IEnumerable<PalpableCatchHitObject> selectPalpableObjects(HitObject h)
{
if (h is PalpableCatchHitObject palpable)
yield return palpable;
foreach (var nested in h.NestedHitObjects.OfType<PalpableCatchHitObject>())
yield return nested;
}
}
} }
} }

View File

@ -2,7 +2,6 @@
// 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 osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
@ -192,24 +191,9 @@ private static void applyOffset(ref float position, float amount)
private static void initialiseHyperDash(IBeatmap beatmap) private static void initialiseHyperDash(IBeatmap beatmap)
{ {
List<PalpableCatchHitObject> palpableObjects = new List<PalpableCatchHitObject>(); var palpableObjects = CatchBeatmap.GetPalpableObjects(beatmap.HitObjects)
.Where(h => h is Fruit || (h is Droplet && h is not TinyDroplet))
foreach (var currentObject in beatmap.HitObjects) .ToArray();
{
if (currentObject is Fruit fruitObject)
palpableObjects.Add(fruitObject);
if (currentObject is JuiceStream)
{
foreach (var juice in currentObject.NestedHitObjects)
{
if (juice is PalpableCatchHitObject palpableObject && !(juice is TinyDroplet))
palpableObjects.Add(palpableObject);
}
}
}
palpableObjects = palpableObjects.OrderBy(h => h.StartTime).ToList();
double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.Difficulty) / 2; double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.Difficulty) / 2;
@ -221,7 +205,7 @@ private static void initialiseHyperDash(IBeatmap beatmap)
int lastDirection = 0; int lastDirection = 0;
double lastExcess = halfCatcherWidth; double lastExcess = halfCatcherWidth;
for (int i = 0; i < palpableObjects.Count - 1; i++) for (int i = 0; i < palpableObjects.Length - 1; i++)
{ {
var currentObject = palpableObjects[i]; var currentObject = palpableObjects[i];
var nextObject = palpableObjects[i + 1]; var nextObject = palpableObjects[i + 1];

View File

@ -5,6 +5,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing; using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Catch.Difficulty.Skills; using osu.Game.Rulesets.Catch.Difficulty.Skills;
using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Mods;
@ -54,13 +55,10 @@ protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(I
List<DifficultyHitObject> objects = new List<DifficultyHitObject>(); List<DifficultyHitObject> objects = new List<DifficultyHitObject>();
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream. // In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
foreach (var hitObject in beatmap.HitObjects foreach (var hitObject in CatchBeatmap.GetPalpableObjects(beatmap.HitObjects))
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects.AsEnumerable() : new[] { obj })
.Cast<CatchHitObject>()
.OrderBy(x => x.StartTime))
{ {
// We want to only consider fruits that contribute to the combo. // We want to only consider fruits that contribute to the combo.
if (hitObject is BananaShower || hitObject is TinyDroplet) if (hitObject is Banana || hitObject is TinyDroplet)
continue; continue;
if (lastObject != null) if (lastObject != null)