mirror of
https://github.com/osukey/osukey.git
synced 2025-08-03 06:36:31 +09:00
Restructure difficulty copy flow to adapt to latest changes
This commit is contained in:
@ -20,7 +20,6 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Stores;
|
||||
|
||||
@ -109,55 +108,73 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a new difficulty to the beatmap set represented by the provided <see cref="BeatmapSetInfo"/>.
|
||||
/// Add a new difficulty to the provided <paramref name="targetBeatmapSet"/> based on the provided <paramref name="referenceWorkingBeatmap"/>.
|
||||
/// The new difficulty will be backed by a <see cref="BeatmapInfo"/> model
|
||||
/// and represented by the returned <see cref="WorkingBeatmap"/>.
|
||||
/// </summary>
|
||||
public virtual WorkingBeatmap CreateNewDifficulty(NewDifficultyCreationParameters creationParameters)
|
||||
/// <remarks>
|
||||
/// Contrary to <see cref="CopyExistingDifficulty"/>, this method does not preserve hitobjects and beatmap-level settings from <paramref name="referenceWorkingBeatmap"/>.
|
||||
/// The created beatmap will have zero hitobjects and will have default settings (including difficulty settings), but will preserve metadata and existing timing points.
|
||||
/// </remarks>
|
||||
/// <param name="targetBeatmapSet">The <see cref="BeatmapSetInfo"/> to add the new difficulty to.</param>
|
||||
/// <param name="referenceWorkingBeatmap">The <see cref="WorkingBeatmap"/> to use as a baseline reference when creating the new difficulty.</param>
|
||||
/// <param name="rulesetInfo">The ruleset with which the new difficulty should be created.</param>
|
||||
public virtual WorkingBeatmap CreateNewDifficulty(BeatmapSetInfo targetBeatmapSet, WorkingBeatmap referenceWorkingBeatmap, RulesetInfo rulesetInfo)
|
||||
{
|
||||
var referenceBeatmap = creationParameters.ReferenceBeatmap;
|
||||
var targetBeatmapSet = creationParameters.BeatmapSet;
|
||||
var playableBeatmap = referenceWorkingBeatmap.GetPlayableBeatmap(rulesetInfo);
|
||||
|
||||
var newBeatmapInfo = new BeatmapInfo(rulesetInfo, new BeatmapDifficulty(), playableBeatmap.Metadata.DeepClone());
|
||||
var newBeatmap = new Beatmap { BeatmapInfo = newBeatmapInfo };
|
||||
foreach (var timingPoint in playableBeatmap.ControlPointInfo.TimingPoints)
|
||||
newBeatmap.ControlPointInfo.Add(timingPoint.Time, timingPoint.DeepClone());
|
||||
|
||||
return addDifficultyToSet(targetBeatmapSet, newBeatmap, referenceWorkingBeatmap.Skin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a copy of the provided <paramref name="referenceWorkingBeatmap"/> to the provided <paramref name="targetBeatmapSet"/>.
|
||||
/// The new difficulty will be backed by a <see cref="BeatmapInfo"/> model
|
||||
/// and represented by the returned <see cref="WorkingBeatmap"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Contrary to <see cref="CreateNewDifficulty"/>, this method creates a nearly-exact copy of <paramref name="referenceWorkingBeatmap"/>
|
||||
/// (with the exception of a few key properties that cannot be copied under any circumstance, like difficulty name, beatmap hash, or online status).
|
||||
/// </remarks>
|
||||
/// <param name="targetBeatmapSet">The <see cref="BeatmapSetInfo"/> to add the copy to.</param>
|
||||
/// <param name="referenceWorkingBeatmap">The <see cref="WorkingBeatmap"/> to be copied.</param>
|
||||
public virtual WorkingBeatmap CopyExistingDifficulty(BeatmapSetInfo targetBeatmapSet, WorkingBeatmap referenceWorkingBeatmap)
|
||||
{
|
||||
var newBeatmap = referenceWorkingBeatmap.GetPlayableBeatmap(referenceWorkingBeatmap.BeatmapInfo.Ruleset).Clone();
|
||||
BeatmapInfo newBeatmapInfo;
|
||||
IBeatmap newBeatmap;
|
||||
|
||||
if (creationParameters.CreateBlank)
|
||||
{
|
||||
newBeatmapInfo = new BeatmapInfo(creationParameters.Ruleset, new BeatmapDifficulty(), referenceBeatmap.Metadata.DeepClone());
|
||||
newBeatmap = new Beatmap { BeatmapInfo = newBeatmapInfo };
|
||||
foreach (var timingPoint in referenceBeatmap.ControlPointInfo.TimingPoints)
|
||||
newBeatmap.ControlPointInfo.Add(timingPoint.Time, timingPoint.DeepClone());
|
||||
}
|
||||
else
|
||||
{
|
||||
newBeatmap = referenceBeatmap.Clone();
|
||||
newBeatmap.BeatmapInfo = newBeatmapInfo = referenceBeatmap.BeatmapInfo.Clone();
|
||||
// assign a new ID to the clone.
|
||||
newBeatmapInfo.ID = Guid.NewGuid();
|
||||
// add "(copy)" suffix to difficulty name to avoid clashes on save.
|
||||
newBeatmapInfo.DifficultyName += " (copy)";
|
||||
// clear the hash, as that's what is used to match .osu files with their corresponding realm beatmaps.
|
||||
newBeatmapInfo.Hash = string.Empty;
|
||||
// clear online properties.
|
||||
newBeatmapInfo.OnlineID = -1;
|
||||
newBeatmapInfo.Status = BeatmapOnlineStatus.None;
|
||||
}
|
||||
newBeatmap.BeatmapInfo = newBeatmapInfo = referenceWorkingBeatmap.BeatmapInfo.Clone();
|
||||
// assign a new ID to the clone.
|
||||
newBeatmapInfo.ID = Guid.NewGuid();
|
||||
// add "(copy)" suffix to difficulty name to avoid clashes on save.
|
||||
newBeatmapInfo.DifficultyName += " (copy)";
|
||||
// clear the hash, as that's what is used to match .osu files with their corresponding realm beatmaps.
|
||||
newBeatmapInfo.Hash = string.Empty;
|
||||
// clear online properties.
|
||||
newBeatmapInfo.OnlineID = -1;
|
||||
newBeatmapInfo.Status = BeatmapOnlineStatus.None;
|
||||
|
||||
return addDifficultyToSet(targetBeatmapSet, newBeatmap, referenceWorkingBeatmap.Skin);
|
||||
}
|
||||
|
||||
private WorkingBeatmap addDifficultyToSet(BeatmapSetInfo targetBeatmapSet, IBeatmap newBeatmap, ISkin beatmapSkin)
|
||||
{
|
||||
// populate circular beatmap set info <-> beatmap info references manually.
|
||||
// several places like `BeatmapModelManager.Save()` or `GetWorkingBeatmap()`
|
||||
// rely on them being freely traversable in both directions for correct operation.
|
||||
targetBeatmapSet.Beatmaps.Add(newBeatmapInfo);
|
||||
newBeatmapInfo.BeatmapSet = targetBeatmapSet;
|
||||
targetBeatmapSet.Beatmaps.Add(newBeatmap.BeatmapInfo);
|
||||
newBeatmap.BeatmapInfo.BeatmapSet = targetBeatmapSet;
|
||||
|
||||
beatmapModelManager.Save(newBeatmapInfo, newBeatmap, creationParameters.ReferenceBeatmapSkin);
|
||||
beatmapModelManager.Save(newBeatmap.BeatmapInfo, newBeatmap, beatmapSkin);
|
||||
|
||||
workingBeatmapCache.Invalidate(targetBeatmapSet);
|
||||
return GetWorkingBeatmap(newBeatmap.BeatmapInfo);
|
||||
}
|
||||
|
||||
// TODO: add back support for making a copy of another difficulty
|
||||
// (likely via a separate `CopyDifficulty()` method).
|
||||
|
||||
/// <summary>
|
||||
/// Delete a beatmap difficulty.
|
||||
/// </summary>
|
||||
|
Reference in New Issue
Block a user