mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 16:13:34 +08:00
Fix first object after break not starting a new combo
This commit is contained in:
parent
87a76b9ee8
commit
cb4568c4a1
@ -1093,5 +1093,20 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
Assert.That(hitObject.Samples.Select(s => s.Volume), Has.All.EqualTo(70));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNewComboAfterBreak()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("break-between-objects.osu"))
|
||||
using (var stream = new LineBufferedReader(resStream))
|
||||
{
|
||||
var beatmap = decoder.Decode(stream);
|
||||
Assert.That(((IHasCombo)beatmap.HitObjects[0]).NewCombo, Is.True);
|
||||
Assert.That(((IHasCombo)beatmap.HitObjects[1]).NewCombo, Is.True);
|
||||
Assert.That(((IHasCombo)beatmap.HitObjects[2]).NewCombo, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +94,6 @@ namespace osu.Game.Tests.Gameplay
|
||||
|
||||
private class TestHitObjectWithCombo : ConvertHitObject, IHasComboInformation
|
||||
{
|
||||
public bool NewCombo { get; set; }
|
||||
public int ComboOffset => 0;
|
||||
|
||||
public Bindable<int> IndexInCurrentComboBindable { get; } = new Bindable<int>();
|
||||
|
||||
public int IndexInCurrentCombo
|
||||
|
15
osu.Game.Tests/Resources/break-between-objects.osu
Normal file
15
osu.Game.Tests/Resources/break-between-objects.osu
Normal file
@ -0,0 +1,15 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
Mode: 0
|
||||
|
||||
[Events]
|
||||
2,200,1200
|
||||
|
||||
[TimingPoints]
|
||||
0,307.692307692308,4,2,1,60,1,0
|
||||
|
||||
[HitObjects]
|
||||
142,99,0,1,0,0:0:0:0:
|
||||
323,88,3000,1,0,0:0:0:0:
|
||||
323,88,4000,1,0,0:0:0:0:
|
@ -93,6 +93,8 @@ namespace osu.Game.Beatmaps.Formats
|
||||
// The parsing order of hitobjects matters in mania difficulty calculation
|
||||
this.beatmap.HitObjects = this.beatmap.HitObjects.OrderBy(h => h.StartTime).ToList();
|
||||
|
||||
postProcessBreaks(this.beatmap);
|
||||
|
||||
foreach (var hitObject in this.beatmap.HitObjects)
|
||||
{
|
||||
applyDefaults(hitObject);
|
||||
@ -100,6 +102,27 @@ namespace osu.Game.Beatmaps.Formats
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the beatmap such that a new combo is started the first hitobject following each break.
|
||||
/// </summary>
|
||||
private void postProcessBreaks(Beatmap beatmap)
|
||||
{
|
||||
int currentBreak = 0;
|
||||
bool forceNewCombo = false;
|
||||
|
||||
foreach (var h in beatmap.HitObjects.OfType<ConvertHitObject>())
|
||||
{
|
||||
while (currentBreak < beatmap.Breaks.Count && beatmap.Breaks[currentBreak].EndTime < h.StartTime)
|
||||
{
|
||||
forceNewCombo = true;
|
||||
currentBreak++;
|
||||
}
|
||||
|
||||
h.NewCombo |= forceNewCombo;
|
||||
forceNewCombo = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyDefaults(HitObject hitObject)
|
||||
{
|
||||
DifficultyControlPoint difficultyControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.DifficultyPointAt(hitObject.StartTime) ?? DifficultyControlPoint.DEFAULT;
|
||||
|
@ -9,16 +9,12 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertHit : ConvertHitObject, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertHit : ConvertHitObject, IHasPosition
|
||||
{
|
||||
public float X => Position.X;
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,12 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition
|
||||
{
|
||||
public float X => Position.X;
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -8,16 +8,12 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertSpinner : ConvertHitObject, IHasDuration, IHasXPosition, IHasCombo
|
||||
internal sealed class ConvertSpinner : ConvertHitObject, IHasDuration, IHasXPosition
|
||||
{
|
||||
public double EndTime => StartTime + Duration;
|
||||
|
||||
public double Duration { get; set; }
|
||||
|
||||
public float X => 256; // Required for CatchBeatmapConverter
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
@ -9,8 +10,12 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <summary>
|
||||
/// A hit object only used for conversion, not actual gameplay.
|
||||
/// </summary>
|
||||
internal abstract class ConvertHitObject : HitObject
|
||||
internal abstract class ConvertHitObject : HitObject, IHasCombo
|
||||
{
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
|
||||
public override Judgement CreateJudgement() => new IgnoreJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
|
||||
|
@ -9,16 +9,12 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertHit : ConvertHitObject, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertHit : ConvertHitObject, IHasPosition
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
public float X => Position.X;
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo, IHasGenerateTicks
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasGenerateTicks
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
@ -17,10 +17,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
|
||||
public bool GenerateTicks { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertSpinner : ConvertHitObject, IHasDuration, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertSpinner : ConvertHitObject, IHasDuration, IHasPosition
|
||||
{
|
||||
public double Duration { get; set; }
|
||||
|
||||
@ -20,9 +20,5 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
public float X => Position.X;
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public int ComboOffset { get; set; }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user