mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 05:02:55 +08:00
Merge pull request #23631 from bdach/fix-velocity-undo
Fix undo/redo not working for slider velocity and sample changes
This commit is contained in:
commit
f908545b9b
@ -92,6 +92,20 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
hitObjectHasVelocity(1, 5);
|
hitObjectHasVelocity(1, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUndo()
|
||||||
|
{
|
||||||
|
clickDifficultyPiece(1);
|
||||||
|
velocityPopoverHasSingleValue(2);
|
||||||
|
|
||||||
|
setVelocityViaPopover(5);
|
||||||
|
hitObjectHasVelocity(1, 5);
|
||||||
|
dismissPopover();
|
||||||
|
|
||||||
|
AddStep("undo", () => Editor.Undo());
|
||||||
|
hitObjectHasVelocity(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMultipleSelectionWithSameSliderVelocity()
|
public void TestMultipleSelectionWithSameSliderVelocity()
|
||||||
{
|
{
|
||||||
|
@ -109,6 +109,21 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
hitObjectHasSampleBank(1, "drum");
|
hitObjectHasSampleBank(1, "drum");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUndo()
|
||||||
|
{
|
||||||
|
clickSamplePiece(1);
|
||||||
|
samplePopoverHasSingleBank("soft");
|
||||||
|
samplePopoverHasSingleVolume(60);
|
||||||
|
|
||||||
|
setVolumeViaPopover(90);
|
||||||
|
hitObjectHasSampleVolume(1, 90);
|
||||||
|
dismissPopover();
|
||||||
|
|
||||||
|
AddStep("undo", () => Editor.Undo());
|
||||||
|
hitObjectHasSampleVolume(1, 60);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMultipleSelectionWithSameSampleVolume()
|
public void TestMultipleSelectionWithSameSampleVolume()
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -15,7 +16,9 @@ using osu.Framework.Graphics.Textures;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
|
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
editorBeatmap.BeginChange();
|
editorBeatmap.BeginChange();
|
||||||
processHitObjects(result, () => newBeatmap ??= readBeatmap(newState));
|
processHitObjects(result, () => newBeatmap ??= readBeatmap(newState));
|
||||||
processTimingPoints(() => newBeatmap ??= readBeatmap(newState));
|
processTimingPoints(() => newBeatmap ??= readBeatmap(newState));
|
||||||
|
processHitObjectLocalData(() => newBeatmap ??= readBeatmap(newState));
|
||||||
editorBeatmap.EndChange();
|
editorBeatmap.EndChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +91,41 @@ namespace osu.Game.Screens.Edit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processHitObjectLocalData(Func<IBeatmap> getNewBeatmap)
|
||||||
|
{
|
||||||
|
// This method handles data that are stored in control points in the legacy format,
|
||||||
|
// but were moved to the hitobjects themselves in lazer.
|
||||||
|
// Specifically, the data being referred to here consists of: slider velocity and sample information.
|
||||||
|
|
||||||
|
// For simplicity, this implementation relies on the editor beatmap already having the same hitobjects in sequence as the new beatmap.
|
||||||
|
// To guarantee that, `processHitObjects()` must be ran prior to this method for correct operation.
|
||||||
|
// This is done to avoid the necessity of reimplementing/reusing parts of LegacyBeatmapDecoder that already treat this data correctly.
|
||||||
|
|
||||||
|
var oldObjects = editorBeatmap.HitObjects;
|
||||||
|
var newObjects = getNewBeatmap().HitObjects;
|
||||||
|
|
||||||
|
Debug.Assert(oldObjects.Count == newObjects.Count);
|
||||||
|
|
||||||
|
foreach (var (oldObject, newObject) in oldObjects.Zip(newObjects))
|
||||||
|
{
|
||||||
|
// if `oldObject` and `newObject` are the same, it means that `oldObject` was inserted into `editorBeatmap` by `processHitObjects()`.
|
||||||
|
// in that case, there is nothing to do (and some of the subsequent changes may even prove destructive).
|
||||||
|
if (ReferenceEquals(oldObject, newObject))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (oldObject is IHasSliderVelocity oldWithVelocity && newObject is IHasSliderVelocity newWithVelocity)
|
||||||
|
oldWithVelocity.SliderVelocity = newWithVelocity.SliderVelocity;
|
||||||
|
|
||||||
|
oldObject.Samples = newObject.Samples;
|
||||||
|
|
||||||
|
if (oldObject is IHasRepeats oldWithRepeats && newObject is IHasRepeats newWithRepeats)
|
||||||
|
{
|
||||||
|
oldWithRepeats.NodeSamples.Clear();
|
||||||
|
oldWithRepeats.NodeSamples.AddRange(newWithRepeats.NodeSamples);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void findChangedIndices(DiffResult result, LegacyDecoder<Beatmap>.Section section, out List<int> removedIndices, out List<int> addedIndices)
|
private void findChangedIndices(DiffResult result, LegacyDecoder<Beatmap>.Section section, out List<int> removedIndices, out List<int> addedIndices)
|
||||||
{
|
{
|
||||||
removedIndices = new List<int>();
|
removedIndices = new List<int>();
|
||||||
|
Loading…
Reference in New Issue
Block a user