mirror of
https://github.com/ppy/osu
synced 2024-12-16 03:45:46 +00:00
Merge pull request #7830 from peppy/fix-2b-relax
Fix relax mod not working correctly on beatmaps with overlapping sliders/spinners
This commit is contained in:
commit
4d6e1e8b55
@ -19,33 +19,46 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
|
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How early before a hitobject's start time to trigger a hit.
|
||||||
|
/// </summary>
|
||||||
|
private const float relax_leniency = 3;
|
||||||
|
|
||||||
public void Update(Playfield playfield)
|
public void Update(Playfield playfield)
|
||||||
{
|
{
|
||||||
bool requiresHold = false;
|
bool requiresHold = false;
|
||||||
bool requiresHit = false;
|
bool requiresHit = false;
|
||||||
|
|
||||||
const float relax_leniency = 3;
|
double time = playfield.Clock.CurrentTime;
|
||||||
|
|
||||||
foreach (var drawable in playfield.HitObjectContainer.AliveObjects)
|
foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType<DrawableOsuHitObject>())
|
||||||
{
|
{
|
||||||
if (!(drawable is DrawableOsuHitObject osuHit))
|
// we are not yet close enough to the object.
|
||||||
|
if (time < h.HitObject.StartTime - relax_leniency)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// already hit or beyond the hittable end time.
|
||||||
|
if (h.IsHit || (h.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double time = osuHit.Clock.CurrentTime;
|
switch (h)
|
||||||
double relativetime = time - osuHit.HitObject.StartTime;
|
|
||||||
|
|
||||||
if (time < osuHit.HitObject.StartTime - relax_leniency) continue;
|
|
||||||
|
|
||||||
if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (osuHit is DrawableHitCircle && osuHit.IsHovered)
|
|
||||||
{
|
{
|
||||||
Debug.Assert(osuHit.HitObject.HitWindows != null);
|
case DrawableHitCircle circle:
|
||||||
requiresHit |= osuHit.HitObject.HitWindows.CanBeHit(relativetime);
|
handleHitCircle(circle);
|
||||||
}
|
break;
|
||||||
|
|
||||||
requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner;
|
case DrawableSlider slider:
|
||||||
|
// Handles cases like "2B" beatmaps, where sliders may be overlapping and simply holding is not enough.
|
||||||
|
if (!slider.HeadCircle.IsHit)
|
||||||
|
handleHitCircle(slider.HeadCircle);
|
||||||
|
|
||||||
|
requiresHold |= slider.Ball.IsHovered || h.IsHovered;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableSpinner _:
|
||||||
|
requiresHold = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiresHit)
|
if (requiresHit)
|
||||||
@ -55,6 +68,15 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
addAction(requiresHold);
|
addAction(requiresHold);
|
||||||
|
|
||||||
|
void handleHitCircle(DrawableHitCircle circle)
|
||||||
|
{
|
||||||
|
if (!circle.IsHovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Debug.Assert(circle.HitObject.HitWindows != null);
|
||||||
|
requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool wasHit;
|
private bool wasHit;
|
||||||
|
Loading…
Reference in New Issue
Block a user