mirror of
https://github.com/ppy/osu.git
synced 2025-01-08 06:36:05 +08:00
Fix stack leniency not applying immediately after change
This commit is contained in:
parent
a8a2e543d5
commit
25b2dfa601
@ -2,6 +2,7 @@
|
|||||||
// 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.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -41,22 +42,22 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
{
|
{
|
||||||
base.PostProcess();
|
base.PostProcess();
|
||||||
|
|
||||||
var osuBeatmap = (Beatmap<OsuHitObject>)Beatmap;
|
var hitObjects = Beatmap.HitObjects as List<OsuHitObject> ?? Beatmap.HitObjects.OfType<OsuHitObject>().ToList();
|
||||||
|
|
||||||
if (osuBeatmap.HitObjects.Count > 0)
|
if (hitObjects.Count > 0)
|
||||||
{
|
{
|
||||||
// Reset stacking
|
// Reset stacking
|
||||||
foreach (var h in osuBeatmap.HitObjects)
|
foreach (var h in hitObjects)
|
||||||
h.StackHeight = 0;
|
h.StackHeight = 0;
|
||||||
|
|
||||||
if (Beatmap.BeatmapInfo.BeatmapVersion >= 6)
|
if (Beatmap.BeatmapInfo.BeatmapVersion >= 6)
|
||||||
applyStacking(osuBeatmap, 0, osuBeatmap.HitObjects.Count - 1);
|
applyStacking(Beatmap.BeatmapInfo, hitObjects, 0, hitObjects.Count - 1);
|
||||||
else
|
else
|
||||||
applyStackingOld(osuBeatmap);
|
applyStackingOld(Beatmap.BeatmapInfo, hitObjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStacking(Beatmap<OsuHitObject> beatmap, int startIndex, int endIndex)
|
private void applyStacking(BeatmapInfo beatmapInfo, List<OsuHitObject> hitObjects, int startIndex, int endIndex)
|
||||||
{
|
{
|
||||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex);
|
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex);
|
||||||
ArgumentOutOfRangeException.ThrowIfNegative(startIndex);
|
ArgumentOutOfRangeException.ThrowIfNegative(startIndex);
|
||||||
@ -64,24 +65,24 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
|
|
||||||
int extendedEndIndex = endIndex;
|
int extendedEndIndex = endIndex;
|
||||||
|
|
||||||
if (endIndex < beatmap.HitObjects.Count - 1)
|
if (endIndex < hitObjects.Count - 1)
|
||||||
{
|
{
|
||||||
// Extend the end index to include objects they are stacked on
|
// Extend the end index to include objects they are stacked on
|
||||||
for (int i = endIndex; i >= startIndex; i--)
|
for (int i = endIndex; i >= startIndex; i--)
|
||||||
{
|
{
|
||||||
int stackBaseIndex = i;
|
int stackBaseIndex = i;
|
||||||
|
|
||||||
for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
|
for (int n = stackBaseIndex + 1; n < hitObjects.Count; n++)
|
||||||
{
|
{
|
||||||
OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
|
OsuHitObject stackBaseObject = hitObjects[stackBaseIndex];
|
||||||
if (stackBaseObject is Spinner) break;
|
if (stackBaseObject is Spinner) break;
|
||||||
|
|
||||||
OsuHitObject objectN = beatmap.HitObjects[n];
|
OsuHitObject objectN = hitObjects[n];
|
||||||
if (objectN is Spinner)
|
if (objectN is Spinner)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = stackBaseObject.GetEndTime();
|
double endTime = stackBaseObject.GetEndTime();
|
||||||
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
double stackThreshold = objectN.TimePreempt * beatmapInfo.StackLeniency;
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
// We are no longer within stacking range of the next object.
|
// We are no longer within stacking range of the next object.
|
||||||
@ -100,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
if (stackBaseIndex > extendedEndIndex)
|
if (stackBaseIndex > extendedEndIndex)
|
||||||
{
|
{
|
||||||
extendedEndIndex = stackBaseIndex;
|
extendedEndIndex = stackBaseIndex;
|
||||||
if (extendedEndIndex == beatmap.HitObjects.Count - 1)
|
if (extendedEndIndex == hitObjects.Count - 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,10 +124,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
* 2 and 1 will be ignored in the i loop because they already have a stack value.
|
* 2 and 1 will be ignored in the i loop because they already have a stack value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OsuHitObject objectI = beatmap.HitObjects[i];
|
OsuHitObject objectI = hitObjects[i];
|
||||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||||
|
|
||||||
double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
double stackThreshold = objectI.TimePreempt * beatmapInfo.StackLeniency;
|
||||||
|
|
||||||
/* If this object is a hitcircle, then we enter this "special" case.
|
/* If this object is a hitcircle, then we enter this "special" case.
|
||||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||||
@ -136,7 +137,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
{
|
{
|
||||||
while (--n >= 0)
|
while (--n >= 0)
|
||||||
{
|
{
|
||||||
OsuHitObject objectN = beatmap.HitObjects[n];
|
OsuHitObject objectN = hitObjects[n];
|
||||||
if (objectN is Spinner) continue;
|
if (objectN is Spinner) continue;
|
||||||
|
|
||||||
double endTime = objectN.GetEndTime();
|
double endTime = objectN.GetEndTime();
|
||||||
@ -164,7 +165,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
for (int j = n + 1; j <= i; j++)
|
for (int j = n + 1; j <= i; j++)
|
||||||
{
|
{
|
||||||
// For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
|
// For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
|
||||||
OsuHitObject objectJ = beatmap.HitObjects[j];
|
OsuHitObject objectJ = hitObjects[j];
|
||||||
if (Vector2Extensions.Distance(objectN.EndPosition, objectJ.Position) < stack_distance)
|
if (Vector2Extensions.Distance(objectN.EndPosition, objectJ.Position) < stack_distance)
|
||||||
objectJ.StackHeight -= offset;
|
objectJ.StackHeight -= offset;
|
||||||
}
|
}
|
||||||
@ -191,7 +192,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
*/
|
*/
|
||||||
while (--n >= startIndex)
|
while (--n >= startIndex)
|
||||||
{
|
{
|
||||||
OsuHitObject objectN = beatmap.HitObjects[n];
|
OsuHitObject objectN = hitObjects[n];
|
||||||
if (objectN is Spinner) continue;
|
if (objectN is Spinner) continue;
|
||||||
|
|
||||||
if (objectI.StartTime - objectN.StartTime > stackThreshold)
|
if (objectI.StartTime - objectN.StartTime > stackThreshold)
|
||||||
@ -208,11 +209,11 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStackingOld(Beatmap<OsuHitObject> beatmap)
|
private void applyStackingOld(BeatmapInfo beatmapInfo, List<OsuHitObject> hitObjects)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < beatmap.HitObjects.Count; i++)
|
for (int i = 0; i < hitObjects.Count; i++)
|
||||||
{
|
{
|
||||||
OsuHitObject currHitObject = beatmap.HitObjects[i];
|
OsuHitObject currHitObject = hitObjects[i];
|
||||||
|
|
||||||
if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
|
if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
|
||||||
continue;
|
continue;
|
||||||
@ -220,11 +221,11 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
double startTime = currHitObject.GetEndTime();
|
double startTime = currHitObject.GetEndTime();
|
||||||
int sliderStack = 0;
|
int sliderStack = 0;
|
||||||
|
|
||||||
for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
|
for (int j = i + 1; j < hitObjects.Count; j++)
|
||||||
{
|
{
|
||||||
double stackThreshold = beatmap.HitObjects[i].TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
double stackThreshold = hitObjects[i].TimePreempt * beatmapInfo.StackLeniency;
|
||||||
|
|
||||||
if (beatmap.HitObjects[j].StartTime - stackThreshold > startTime)
|
if (hitObjects[j].StartTime - stackThreshold > startTime)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// The start position of the hitobject, or the position at the end of the path if the hitobject is a slider
|
// The start position of the hitobject, or the position at the end of the path if the hitobject is a slider
|
||||||
@ -239,17 +240,17 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
// Effects of this can be seen on https://osu.ppy.sh/beatmapsets/243#osu/1146 at sliders around 86647 ms, where
|
// Effects of this can be seen on https://osu.ppy.sh/beatmapsets/243#osu/1146 at sliders around 86647 ms, where
|
||||||
// if we use `EndTime` here it would result in unexpected stacking.
|
// if we use `EndTime` here it would result in unexpected stacking.
|
||||||
|
|
||||||
if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
|
if (Vector2Extensions.Distance(hitObjects[j].Position, currHitObject.Position) < stack_distance)
|
||||||
{
|
{
|
||||||
currHitObject.StackHeight++;
|
currHitObject.StackHeight++;
|
||||||
startTime = beatmap.HitObjects[j].StartTime;
|
startTime = hitObjects[j].StartTime;
|
||||||
}
|
}
|
||||||
else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, position2) < stack_distance)
|
else if (Vector2Extensions.Distance(hitObjects[j].Position, position2) < stack_distance)
|
||||||
{
|
{
|
||||||
// Case for sliders - bump notes down and right, rather than up and left.
|
// Case for sliders - bump notes down and right, rather than up and left.
|
||||||
sliderStack++;
|
sliderStack++;
|
||||||
beatmap.HitObjects[j].StackHeight -= sliderStack;
|
hitObjects[j].StackHeight -= sliderStack;
|
||||||
startTime = beatmap.HitObjects[j].StartTime;
|
startTime = hitObjects[j].StartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Setup
|
|||||||
private void updateBeatmap()
|
private void updateBeatmap()
|
||||||
{
|
{
|
||||||
Beatmap.BeatmapInfo.StackLeniency = stackLeniency.Current.Value;
|
Beatmap.BeatmapInfo.StackLeniency = stackLeniency.Current.Value;
|
||||||
|
Beatmap.UpdateAllHitObjects();
|
||||||
Beatmap.SaveState();
|
Beatmap.SaveState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
BeatmapSkin.BeatmapSkinChanged += SaveState;
|
BeatmapSkin.BeatmapSkinChanged += SaveState;
|
||||||
}
|
}
|
||||||
|
|
||||||
beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapProcessor(PlayableBeatmap);
|
beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset.CreateInstance().CreateBeatmapProcessor(this);
|
||||||
|
|
||||||
foreach (var obj in HitObjects)
|
foreach (var obj in HitObjects)
|
||||||
trackStartTime(obj);
|
trackStartTime(obj);
|
||||||
|
Loading…
Reference in New Issue
Block a user