Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SampleControlPoint and DifficultyControlPoint from HitObject #23308

Merged
merged 52 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
a4c6850
made the SampleControlPoint and DifficultyControlPoint obsolete
OliBomby Apr 25, 2023
ea1e6e9
Add LegacyContext
OliBomby Apr 25, 2023
891b87a
remove ApplyLegacyInfo method
OliBomby Apr 25, 2023
bf1951f
Fix incorrect xmldoc
OliBomby Apr 25, 2023
97910d6
remove unused directives
OliBomby Apr 25, 2023
c37875b
remove hitobject SampleControlPoint usage from LegacyBeatmapEncoder
OliBomby Apr 25, 2023
a634617
Fix file header notice
OliBomby Apr 25, 2023
ebe1d85
remove other usages of hitobject SampleControlPoint
OliBomby Apr 25, 2023
065464d
Fixed DifficultyPointPiece
OliBomby Apr 25, 2023
c23a7b0
add missing }
OliBomby Apr 25, 2023
66eda40
fix implementations of IHasSliderVelocity
OliBomby Apr 25, 2023
755ad25
clean code
OliBomby Apr 25, 2023
e4b64bd
clean up code stuff
OliBomby Apr 25, 2023
e27c4df
Invoke ApplyDefaultsToSelf
OliBomby Apr 26, 2023
6c70948
Remove IContext & add IHasGenerateTicks
OliBomby Apr 26, 2023
39d9f0c
removing using
OliBomby Apr 26, 2023
87ca0f5
Update SamplePointPiece.cs
OliBomby Apr 26, 2023
d97daee
remove all non-test usage of SampleControlPoint
OliBomby Apr 26, 2023
c6fc180
remove all test usages of SampleControlPoint
OliBomby Apr 26, 2023
5accb05
fix invalidoperation exception
OliBomby Apr 26, 2023
1b4f437
fixed sample control point applying
OliBomby Apr 26, 2023
9f8d7bc
fix usings
OliBomby Apr 26, 2023
c44f71a
remove all regular usage of DifficultyControlPoint
OliBomby Apr 26, 2023
354cd23
removed all usage of hitobject's DifficultyControlPoint
OliBomby Apr 26, 2023
f7c8403
remove bank default value
OliBomby Apr 28, 2023
ffcc8e9
fix legacy parser incorrectly assigning sample info for sliders
OliBomby Apr 29, 2023
92efd04
fix sample of drumroll ticks being bankless
OliBomby Apr 29, 2023
a6e780a
Update CheckMutedObjectsTest.cs
OliBomby Apr 29, 2023
8311122
fix null sample
OliBomby Apr 29, 2023
1eb2e35
fix ticks not being generated by default
OliBomby Apr 30, 2023
e7a478c
Update convert-samples-expected-conversion.json
OliBomby Apr 30, 2023
79f3cfe
fix 0 velocity juicestream
OliBomby Apr 30, 2023
139a1d7
fix legacy encoder writing sample info while not writing node samples
OliBomby Apr 30, 2023
4a0ff04
pass new hitobject properties through beatmap converters
OliBomby Apr 30, 2023
41d4894
add min and max value to SliderVelocity
OliBomby Apr 30, 2023
608fa3c
Merge remote-tracking branch 'upstream/master' into sample-control-po…
OliBomby Apr 30, 2023
2a94757
Make sure the first object you place has bank and volume
OliBomby Apr 30, 2023
cef9f73
dont assign custom sample bank and volume to hitobjects in non-mania …
OliBomby May 1, 2023
27cfadc
add sample info to Banana and SpinnerBonusTick
OliBomby May 1, 2023
8302bb1
dont encode custom sample bank for objects without legacy samples
OliBomby May 1, 2023
8c21fdd
remove all redundancies from encoded control points
OliBomby May 1, 2023
e3c384c
Merge branch 'master' into sample-control-points
peppy May 2, 2023
8a536c1
Fix non-block namespace usage
peppy May 2, 2023
c2ad8c2
Fix comment 1 osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs
OliBomby May 2, 2023
2e018c8
Fix comment 2 osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs
OliBomby May 2, 2023
d2d81bb
remove redundant zero check in sv calculation
OliBomby May 2, 2023
90d98cd
remove constructor argument from Banana
OliBomby May 2, 2023
16c624f
Ensure `static` banana samples are not mutated
peppy May 3, 2023
588a4e6
Move pragma disable to top of `LegacyBeatmapDecoder`
peppy May 3, 2023
cca15f9
Refactor `applyLegacyInfoAndDefaults` for legibility
peppy May 3, 2023
48fd998
Split out default and sample application
peppy May 3, 2023
f930c4b
Move `struct` to bottom of file
peppy May 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void TestBasicPlacement()
AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1]));
AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0]));
AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1]));
AddAssert("default slider velocity", () => lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
AddAssert("default slider velocity", () => lastObject.SliderVelocityBindable.IsDefault);
}

[Test]
Expand Down Expand Up @@ -76,7 +76,7 @@ public void TestSliderVelocityChange()
addPlacementSteps(times, positions);
addPathCheckStep(times, positions);

AddAssert("slider velocity changed", () => !lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
AddAssert("slider velocity changed", () => !lastObject.SliderVelocityBindable.IsDefault);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ public void TestSliderVelocityChange()
double[] times = { 100, 300 };
float[] positions = { 200, 300 };
addBlueprintStep(times, positions);
AddAssert("default slider velocity", () => hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
AddAssert("default slider velocity", () => hitObject.SliderVelocityBindable.IsDefault);

addDragStartStep(times[1], positions[1]);
AddMouseMoveStep(times[1], 400);
AddAssert("slider velocity changed", () => !hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
AddAssert("slider velocity changed", () => !hitObject.SliderVelocityBindable.IsDefault);
}

[Test]
Expand Down
4 changes: 3 additions & 1 deletion osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, I
var xPositionData = obj as IHasXPosition;
var yPositionData = obj as IHasYPosition;
var comboData = obj as IHasCombo;
var sliderVelocityData = obj as IHasSliderVelocity;

switch (obj)
{
Expand All @@ -41,7 +42,8 @@ protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, I
NewCombo = comboData?.NewCombo ?? false,
ComboOffset = comboData?.ComboOffset ?? 0,
LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0,
LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y
LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y,
SliderVelocity = sliderVelocityData?.SliderVelocity ?? 1
}.Yield();

case IHasDuration endTime:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void InitializeFromHitObject(JuiceStream hitObject)
public void UpdateHitObjectFromPath(JuiceStream hitObject)
{
// The SV setting may need to be changed for the current path.
var svBindable = hitObject.DifficultyControlPoint.SliderVelocityBindable;
var svBindable = hitObject.SliderVelocityBindable;
double svToVelocityFactor = hitObject.Velocity / svBindable.Value;
double requiredVelocity = path.ComputeRequiredVelocity();

Expand Down
8 changes: 4 additions & 4 deletions osu.Game.Rulesets.Catch/Objects/Banana.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ public class Banana : PalpableCatchHitObject, IHasComboInformation

public override Judgement CreateJudgement() => new CatchBananaJudgement();

private static readonly List<HitSampleInfo> samples = new List<HitSampleInfo> { new BananaHitSampleInfo() };
private static readonly IList<HitSampleInfo> default_banana_samples = new List<HitSampleInfo> { new BananaHitSampleInfo() }.AsReadOnly();

public Banana()
{
Samples = samples;
Samples = default_banana_samples;
}

// override any external colour changes with banananana
Expand All @@ -47,13 +47,13 @@ private Color4 getBananaColour()
}
}

private class BananaHitSampleInfo : HitSampleInfo, IEquatable<BananaHitSampleInfo>
public class BananaHitSampleInfo : HitSampleInfo, IEquatable<BananaHitSampleInfo>
{
private static readonly string[] lookup_names = { "Gameplay/metronomelow", "Gameplay/catch-banana" };

public override IEnumerable<string> LookupNames => lookup_names;

public BananaHitSampleInfo(int volume = 0)
public BananaHitSampleInfo(int volume = 100)
: base(string.Empty, volume: volume)
{
}
Expand Down
3 changes: 3 additions & 0 deletions osu.Game.Rulesets.Catch/Objects/BananaShower.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Threading;
using osu.Game.Audio;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;

Expand Down Expand Up @@ -39,6 +41,7 @@ private void createBananas(CancellationToken cancellationToken)
{
StartTime = time,
BananaIndex = i,
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(GetSampleInfo().Volume) }
});

time += spacing;
Expand Down
20 changes: 17 additions & 3 deletions osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Threading;
using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
Expand All @@ -16,7 +17,7 @@

namespace osu.Game.Rulesets.Catch.Objects
{
public class JuiceStream : CatchHitObject, IHasPathWithRepeats
public class JuiceStream : CatchHitObject, IHasPathWithRepeats, IHasSliderVelocity
{
/// <summary>
/// Positional distance that results in a duration of one second, before any speed adjustments.
Expand All @@ -27,17 +28,30 @@ public class JuiceStream : CatchHitObject, IHasPathWithRepeats

public int RepeatCount { get; set; }

public BindableNumber<double> SliderVelocityBindable { get; } = new BindableDouble(1)
{
Precision = 0.01,
MinValue = 0.1,
MaxValue = 10
};

public double SliderVelocity
{
get => SliderVelocityBindable.Value;
set => SliderVelocityBindable.Value = value;
}

[JsonIgnore]
private double velocityFactor;

[JsonIgnore]
private double tickDistanceFactor;

[JsonIgnore]
public double Velocity => velocityFactor * DifficultyControlPoint.SliderVelocity;
public double Velocity => velocityFactor * SliderVelocity;

[JsonIgnore]
public double TickDistance => tickDistanceFactor * DifficultyControlPoint.SliderVelocity;
public double TickDistance => tickDistanceFactor * SliderVelocity;

/// <summary>
/// The length of one span of this <see cref="JuiceStream"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats;
using osu.Game.Utils;

namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
Expand Down Expand Up @@ -49,15 +48,14 @@ public DistanceObjectPatternGenerator(LegacyRandom random, HitObject hitObject,
Debug.Assert(distanceData != null);

TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime);
DifficultyControlPoint difficultyPoint = hitObject.DifficultyControlPoint;

double beatLength;
#pragma warning disable 618
if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint)
#pragma warning restore 618
beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier;
if (hitObject.LegacyBpmMultiplier.HasValue)
beatLength = timingPoint.BeatLength * hitObject.LegacyBpmMultiplier.Value;
else if (hitObject is IHasSliderVelocity hasSliderVelocity)
beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity;
else
beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity;
beatLength = timingPoint.BeatLength;

SpanCount = repeatsData?.SpanCount() ?? 1;
StartTime = (int)Math.Round(hitObject.StartTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,7 @@ protected override void LoadSamples()
{
// Note: base.LoadSamples() isn't called since the slider plays the tail's hitsounds for the time being.

if (HitObject.SampleControlPoint == null)
{
throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}."
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
}

slidingSample.Samples = HitObject.CreateSlidingSamples().Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast<ISampleInfo>().ToArray();
slidingSample.Samples = HitObject.CreateSlidingSamples().Cast<ISampleInfo>().ToArray();
}

public override void StopAllSamples()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
["Gameplay/soft-hitnormal"],
["Gameplay/drum-hitnormal"]
],
"Samples": ["Gameplay/-hitnormal"]
"Samples": ["Gameplay/normal-hitnormal"]
}, {
"StartTime": 1875.0,
"EndTime": 2750.0,
Expand All @@ -19,7 +19,7 @@
["Gameplay/soft-hitnormal"],
["Gameplay/drum-hitnormal"]
],
"Samples": ["Gameplay/-hitnormal"]
"Samples": ["Gameplay/normal-hitnormal"]
}]
}, {
"StartTime": 3750.0,
Expand Down
3 changes: 1 addition & 2 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ public void TestMergeSliderSlider()
var mergedSlider = (Slider)EditorBeatmap.SelectedHitObjects.First();
return slider1 is not null && mergedSlider.HeadCircle.Samples.SequenceEqual(slider1.HeadCircle.Samples)
&& mergedSlider.TailCircle.Samples.SequenceEqual(slider1.TailCircle.Samples)
&& mergedSlider.Samples.SequenceEqual(slider1.Samples)
&& mergedSlider.SampleControlPoint.IsRedundant(slider1.SampleControlPoint);
&& mergedSlider.Samples.SequenceEqual(slider1.Samples);
});

AddAssert("slider end is at same completion for last slider", () =>
Expand Down
10 changes: 3 additions & 7 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,8 @@ public void TestSplitRetainsHitsounds()
{
if (slider is null) return;

slider.SampleControlPoint.SampleBank = "soft";
slider.SampleControlPoint.SampleVolume = 70;
sample = new HitSampleInfo("hitwhistle");
slider.Samples.Add(sample);
sample = new HitSampleInfo("hitwhistle", "soft", volume: 70);
slider.Samples.Add(sample.With());
});

AddStep("select added slider", () =>
Expand All @@ -207,9 +205,7 @@ public void TestSplitRetainsHitsounds()
AddAssert("sliders have hitsounds", hasHitsounds);

bool hasHitsounds() => sample is not null &&
EditorBeatmap.HitObjects.All(o => o.SampleControlPoint.SampleBank == "soft" &&
o.SampleControlPoint.SampleVolume == 70 &&
o.Samples.Contains(sample));
EditorBeatmap.HitObjects.All(o => o.Samples.Contains(sample));
}

private bool sliderCreatedFor(Slider s, double startTime, double endTime, params (Vector2 pos, PathType? pathType)[] expectedControlPoints)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ bool matches(HitCircle circle, double time, Vector2 position, bool startsNewComb
Precision.AlmostEquals(circle.StartTime, time, 1)
&& Precision.AlmostEquals(circle.Position, position, 0.01f)
&& circle.NewCombo == startsNewCombo
&& circle.Samples.SequenceEqual(slider.HeadCircle.Samples)
&& circle.SampleControlPoint.IsRedundant(slider.SampleControlPoint);
&& circle.Samples.SequenceEqual(slider.HeadCircle.Samples);
}

private bool sliderRestored(Slider slider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ private class TestSlider : Slider
{
public TestSlider()
{
DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f };
SliderVelocity = 0.1f;

DefaultsApplied += _ =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Replays;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
Expand Down Expand Up @@ -47,7 +46,7 @@ public void TestMaximumDistanceTrackingWithoutMovement(
{
StartTime = time_slider_start,
Position = new Vector2(0, 0),
DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = velocity },
SliderVelocity = velocity,
Path = new SliderPath(PathType.Linear, new[]
{
Vector2.Zero,
Expand Down
3 changes: 1 addition & 2 deletions osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using NUnit.Framework;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Replays;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
Expand Down Expand Up @@ -350,7 +349,7 @@ private void performTest(List<ReplayFrame> frames)
{
StartTime = time_slider_start,
Position = new Vector2(0, 0),
DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f },
SliderVelocity = 0.1f,
Path = new SliderPath(PathType.PerfectCurve, new[]
{
Vector2.Zero,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ private class TestSlider : Slider
{
public TestSlider()
{
DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f };
SliderVelocity = 0.1f;

DefaultsApplied += _ =>
{
Expand Down
6 changes: 5 additions & 1 deletion osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original
{
var positionData = original as IHasPosition;
var comboData = original as IHasCombo;
var sliderVelocityData = original as IHasSliderVelocity;
var generateTicksData = original as IHasGenerateTicks;

switch (original)
{
Expand All @@ -47,7 +49,9 @@ protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original
LegacyLastTickOffset = (original as IHasLegacyLastTickOffset)?.LegacyLastTickOffset,
// prior to v8, speed multipliers don't adjust for how many ticks are generated over the same distance.
// this results in more (or less) ticks being generated in <v8 maps for the same time duration.
TickDistanceMultiplier = beatmap.BeatmapInfo.BeatmapVersion < 8 ? 1f / ((LegacyControlPointInfo)beatmap.ControlPointInfo).DifficultyPointAt(original.StartTime).SliderVelocity : 1
TickDistanceMultiplier = beatmap.BeatmapInfo.BeatmapVersion < 8 ? 1f / ((LegacyControlPointInfo)beatmap.ControlPointInfo).DifficultyPointAt(original.StartTime).SliderVelocity : 1,
GenerateTicks = generateTicksData?.GenerateTicks ?? true,
SliderVelocity = sliderVelocityData?.SliderVelocity ?? 1,
}.Yield();

case IHasDuration endTimeData:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
Expand Down Expand Up @@ -83,11 +82,10 @@ public override void UpdateTimeAndPosition(SnapResult result)
case SliderPlacementState.Initial:
BeginPlacement();

var nearestDifficultyPoint = editorBeatmap.HitObjects
.LastOrDefault(h => h is Slider && h.GetEndTime() < HitObject.StartTime)?
.DifficultyControlPoint?.DeepClone() as DifficultyControlPoint;
double? nearestSliderVelocity = (editorBeatmap.HitObjects
.LastOrDefault(h => h is Slider && h.GetEndTime() < HitObject.StartTime) as Slider)?.SliderVelocity;

HitObject.DifficultyControlPoint = nearestDifficultyPoint ?? new DifficultyControlPoint();
HitObject.SliderVelocity = nearestSliderVelocity ?? 1;
HitObject.Position = ToLocalSpace(result.ScreenSpacePosition);

// Replacing the DifficultyControlPoint above doesn't trigger any kind of invalidation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
Expand Down Expand Up @@ -311,17 +310,11 @@ private void splitControlPoints(List<PathControlPoint> controlPointsToSplitAt)
var splitControlPoints = controlPoints.Take(index + 1).ToList();
controlPoints.RemoveRange(0, index);

// Turn the control points which were split off into a new slider.
var samplePoint = (SampleControlPoint)HitObject.SampleControlPoint.DeepClone();
var difficultyPoint = (DifficultyControlPoint)HitObject.DifficultyControlPoint.DeepClone();

var newSlider = new Slider
{
StartTime = HitObject.StartTime,
Position = HitObject.Position + splitControlPoints[0].Position,
NewCombo = HitObject.NewCombo,
SampleControlPoint = samplePoint,
DifficultyControlPoint = difficultyPoint,
LegacyLastTickOffset = HitObject.LegacyLastTickOffset,
Samples = HitObject.Samples.Select(s => s.With()).ToList(),
RepeatCount = HitObject.RepeatCount,
Expand Down Expand Up @@ -378,15 +371,11 @@ private void convertToStream()

Vector2 position = HitObject.Position + HitObject.Path.PositionAt(pathPosition);

var samplePoint = (SampleControlPoint)HitObject.SampleControlPoint.DeepClone();
samplePoint.Time = time;

editorBeatmap.Add(new HitCircle
{
StartTime = time,
Position = position,
NewCombo = i == 0 && HitObject.NewCombo,
SampleControlPoint = samplePoint,
Samples = HitObject.HeadCircle.Samples.Select(s => s.With()).ToList()
});

Expand Down
Loading