1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-23 08:27:23 +08:00

Merge pull request #30973 from frenzibyte/copy-effect-points

Preserve effect point specifications when creating blank difficulties
This commit is contained in:
Dan Balasescu 2024-12-09 16:13:52 +09:00 committed by GitHub
commit 1b8d9370aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 117 additions and 0 deletions

View File

@ -19,6 +19,7 @@ using osu.Game.Overlays.Dialog;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
@ -154,6 +155,7 @@ namespace osu.Game.Tests.Visual.Editing
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = firstDifficultyName);
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
AddStep("add effect point", () => EditorBeatmap.ControlPointInfo.Add(500, new EffectControlPoint { KiaiMode = true }));
AddStep("add hitobjects", () => EditorBeatmap.AddRange(new[]
{
new HitCircle
@ -200,6 +202,11 @@ namespace osu.Game.Tests.Visual.Editing
var timingPoint = EditorBeatmap.ControlPointInfo.TimingPoints.Single();
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
});
AddAssert("created difficulty has effect points", () =>
{
var effectPoint = EditorBeatmap.ControlPointInfo.EffectPoints.Single();
return effectPoint.Time == 500 && effectPoint.KiaiMode && effectPoint.ScrollSpeedBindable.IsDefault;
});
AddAssert("created difficulty has no objects", () => EditorBeatmap.HitObjects.Count == 0);
AddAssert("status is modified", () => EditorBeatmap.BeatmapInfo.Status == BeatmapOnlineStatus.LocallyModified);
@ -219,6 +226,104 @@ namespace osu.Game.Tests.Visual.Editing
});
}
[Test]
public void TestCreateNewDifficultyWithScrollSpeed_SameRuleset()
{
string firstDifficultyName = Guid.NewGuid().ToString();
AddStep("save beatmap", () => Editor.Save());
AddStep("create new difficulty", () => Editor.CreateNewDifficulty(new ManiaRuleset().RulesetInfo));
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = firstDifficultyName);
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
AddStep("add effect points", () =>
{
EditorBeatmap.ControlPointInfo.Add(250, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.05 });
EditorBeatmap.ControlPointInfo.Add(500, new EffectControlPoint { KiaiMode = true, ScrollSpeed = 0.1 });
EditorBeatmap.ControlPointInfo.Add(750, new EffectControlPoint { KiaiMode = true, ScrollSpeed = 0.15 });
EditorBeatmap.ControlPointInfo.Add(1000, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.2 });
EditorBeatmap.ControlPointInfo.Add(1500, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.3 });
});
AddStep("save beatmap", () => Editor.Save());
AddStep("create new difficulty", () => Editor.CreateNewDifficulty(new ManiaRuleset().RulesetInfo));
AddUntilStep("wait for dialog", () => DialogOverlay.CurrentDialog is CreateNewDifficultyDialog);
AddStep("confirm creation with no objects", () => DialogOverlay.CurrentDialog!.PerformOkAction());
AddUntilStep("wait for created", () =>
{
string? difficultyName = Editor.ChildrenOfType<EditorBeatmap>().SingleOrDefault()?.BeatmapInfo.DifficultyName;
return difficultyName != null && difficultyName != firstDifficultyName;
});
AddAssert("created difficulty has timing point", () =>
{
var timingPoint = EditorBeatmap.ControlPointInfo.TimingPoints.Single();
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
});
AddAssert("created difficulty has effect points", () =>
{
return EditorBeatmap.ControlPointInfo.EffectPoints.SequenceEqual(new[]
{
new EffectControlPoint { Time = 250, KiaiMode = false, ScrollSpeed = 0.05 },
new EffectControlPoint { Time = 500, KiaiMode = true, ScrollSpeed = 0.1 },
new EffectControlPoint { Time = 750, KiaiMode = true, ScrollSpeed = 0.15 },
new EffectControlPoint { Time = 1000, KiaiMode = false, ScrollSpeed = 0.2 },
new EffectControlPoint { Time = 1500, KiaiMode = false, ScrollSpeed = 0.3 },
});
});
}
[Test]
public void TestCreateNewDifficultyWithScrollSpeed_DifferentRuleset()
{
string firstDifficultyName = Guid.NewGuid().ToString();
AddStep("save beatmap", () => Editor.Save());
AddStep("create new difficulty", () => Editor.CreateNewDifficulty(new ManiaRuleset().RulesetInfo));
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = firstDifficultyName);
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
AddStep("add effect points", () =>
{
EditorBeatmap.ControlPointInfo.Add(250, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.05 });
EditorBeatmap.ControlPointInfo.Add(500, new EffectControlPoint { KiaiMode = true, ScrollSpeed = 0.1 });
EditorBeatmap.ControlPointInfo.Add(750, new EffectControlPoint { KiaiMode = true, ScrollSpeed = 0.15 });
EditorBeatmap.ControlPointInfo.Add(1000, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.2 });
EditorBeatmap.ControlPointInfo.Add(1500, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.3 });
});
AddStep("save beatmap", () => Editor.Save());
AddStep("create new difficulty", () => Editor.CreateNewDifficulty(new TaikoRuleset().RulesetInfo));
AddUntilStep("wait for created", () =>
{
string? difficultyName = Editor.ChildrenOfType<EditorBeatmap>().SingleOrDefault()?.BeatmapInfo.DifficultyName;
return difficultyName != null && difficultyName != firstDifficultyName;
});
AddAssert("created difficulty has timing point", () =>
{
var timingPoint = EditorBeatmap.ControlPointInfo.TimingPoints.Single();
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
});
AddAssert("created difficulty has effect points", () =>
{
// since this difficulty is on another ruleset, scroll speed specifications are completely reset,
// therefore discarding some effect points in the process due to being redundant.
return EditorBeatmap.ControlPointInfo.EffectPoints.SequenceEqual(new[]
{
new EffectControlPoint { Time = 500, KiaiMode = true },
new EffectControlPoint { Time = 1000, KiaiMode = false },
});
});
}
[Test]
public void TestCopyDifficulty()
{

View File

@ -15,6 +15,7 @@ using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
using osu.Game.Extensions;
@ -154,9 +155,20 @@ namespace osu.Game.Beatmaps
DifficultyName = NamingUtils.GetNextBestName(targetBeatmapSet.Beatmaps.Select(b => b.DifficultyName), "New Difficulty")
};
var newBeatmap = new Beatmap { BeatmapInfo = newBeatmapInfo };
foreach (var timingPoint in referenceWorkingBeatmap.Beatmap.ControlPointInfo.TimingPoints)
newBeatmap.ControlPointInfo.Add(timingPoint.Time, timingPoint.DeepClone());
foreach (var effectPoint in referenceWorkingBeatmap.Beatmap.ControlPointInfo.EffectPoints)
{
var clonedEffectPoint = (EffectControlPoint)effectPoint.DeepClone();
if (!rulesetInfo.Equals(referenceWorkingBeatmap.BeatmapInfo.Ruleset))
clonedEffectPoint.ScrollSpeedBindable.SetDefault();
newBeatmap.ControlPointInfo.Add(clonedEffectPoint.Time, clonedEffectPoint);
}
return addDifficultyToSet(targetBeatmapSet, newBeatmap, referenceWorkingBeatmap.Skin);
}