1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:17:26 +08:00

Attempt to not break per-hitobject hitwindows

This commit is contained in:
smoogipoo 2019-09-02 18:58:13 +09:00
parent 8302658186
commit 90671e0617
2 changed files with 44 additions and 17 deletions

View File

@ -6,9 +6,11 @@ using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.Objects;
using System;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Replays;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Scoring;
@ -36,6 +38,8 @@ namespace osu.Game.Rulesets.Osu.Replays
/// </summary>
private readonly double reactionTime;
private readonly HitWindows defaultHitWindows;
/// <summary>
/// What easing to use when moving between hitobjects
/// </summary>
@ -50,6 +54,9 @@ namespace osu.Game.Rulesets.Osu.Replays
{
// Already superhuman, but still somewhat realistic
reactionTime = ApplyModsToRate(100);
defaultHitWindows = new OsuHitWindows();
defaultHitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
}
#endregion
@ -91,21 +98,49 @@ namespace osu.Game.Rulesets.Osu.Replays
{
double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime;
HitWindows hitWindows = null;
switch (h)
{
case HitCircle hitCircle:
hitWindows = hitCircle.HitWindows;
break;
case Slider slider:
hitWindows = slider.TailCircle.HitWindows;
break;
case Spinner _:
hitWindows = defaultHitWindows;
break;
}
Debug.Assert(hitWindows != null);
// Make the cursor stay at a hitObject as long as possible (mainly for autopilot).
if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50)
if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner))
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50)
else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner))
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Good) > endTime + HitWindows.HalfWindowFor(HitResult.Good) + 50)
else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Good) > endTime + hitWindows.HalfWindowFor(HitResult.Good) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner))
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
}

View File

@ -29,11 +29,6 @@ namespace osu.Game.Rulesets.Osu.Replays
/// </summary>
protected readonly double FrameDelay;
/// <summary>
/// The <see cref="HitObject"/> hit windows.
/// </summary>
protected readonly HitWindows HitWindows;
#endregion
#region Construction / Initialisation
@ -48,9 +43,6 @@ namespace osu.Game.Rulesets.Osu.Replays
// We are using ApplyModsToRate and not ApplyModsToTime to counteract the speed up / slow down from HalfTime / DoubleTime so that we remain at a constant framerate of 60 fps.
FrameDelay = ApplyModsToRate(1000.0 / 60.0);
HitWindows = new OsuHitWindows();
HitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
}
#endregion