diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index cd818941ff..4191771116 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -285,7 +285,8 @@ namespace osu.Game.Beatmaps
///
/// The query.
/// The first result for the provided query, or null if no results were found.
- public BeatmapInfo? QueryBeatmap(Expression> query) => Realm.Run(r => r.All().Filter($"{nameof(BeatmapInfo.BeatmapSet)}.{nameof(BeatmapSetInfo.DeletePending)} == false").FirstOrDefault(query)?.Detach());
+ public BeatmapInfo? QueryBeatmap(Expression> query) => Realm.Run(r =>
+ r.All().Filter($"{nameof(BeatmapInfo.BeatmapSet)}.{nameof(BeatmapSetInfo.DeletePending)} == false").FirstOrDefault(query)?.Detach());
///
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
@@ -313,6 +314,23 @@ namespace osu.Game.Beatmaps
});
}
+ public void ResetAllOffsets()
+ {
+ const string reset_complete_message = "All offsets have been reset!";
+ Realm.Write(r =>
+ {
+ var items = r.All();
+
+ foreach (var beatmap in items)
+ {
+ if (beatmap.UserSettings.Offset != 0)
+ beatmap.UserSettings.Offset = 0;
+ }
+
+ PostNotification?.Invoke(new ProgressCompletionNotification { Text = reset_complete_message });
+ });
+ }
+
public void Delete(Expression>? filter = null, bool silent = false)
{
Realm.Run(r =>
diff --git a/osu.Game/Localisation/DeleteConfirmationContentStrings.cs b/osu.Game/Localisation/DeleteConfirmationContentStrings.cs
index d781fadbce..2b2f4dda54 100644
--- a/osu.Game/Localisation/DeleteConfirmationContentStrings.cs
+++ b/osu.Game/Localisation/DeleteConfirmationContentStrings.cs
@@ -19,6 +19,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString BeatmapVideos => new TranslatableString(getKey(@"beatmap_videos"), @"Are you sure you want to delete all beatmaps videos? This cannot be undone!");
+ ///
+ /// "Are you sure you want to reset all local beatmap offsets? This cannot be undone!"
+ ///
+ public static LocalisableString Offsets => new TranslatableString(getKey(@"offsets"), @"Are you sure you want to reset all local beatmap offsets? This cannot be undone!");
+
///
/// "Are you sure you want to delete all skins? This cannot be undone!"
///
diff --git a/osu.Game/Localisation/MaintenanceSettingsStrings.cs b/osu.Game/Localisation/MaintenanceSettingsStrings.cs
index 03e15e8393..6d5e0d5e0e 100644
--- a/osu.Game/Localisation/MaintenanceSettingsStrings.cs
+++ b/osu.Game/Localisation/MaintenanceSettingsStrings.cs
@@ -59,6 +59,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString DeleteAllBeatmapVideos => new TranslatableString(getKey(@"delete_all_beatmap_videos"), @"Delete ALL beatmap videos");
+ ///
+ /// "Reset ALL beatmap offsets"
+ ///
+ public static LocalisableString ResetAllOffsets => new TranslatableString(getKey(@"reset_all_offsets"), @"Reset ALL beatmap offsets");
+
///
/// "Delete ALL scores"
///
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs
index d0a8fc7d2c..597e03fab2 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs
@@ -16,6 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
private SettingsButton deleteBeatmapsButton = null!;
private SettingsButton deleteBeatmapVideosButton = null!;
+ private SettingsButton resetOffsetsButton = null!;
private SettingsButton restoreButton = null!;
private SettingsButton undeleteButton = null!;
@@ -47,6 +48,20 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}, DeleteConfirmationContentStrings.BeatmapVideos));
}
});
+
+ Add(resetOffsetsButton = new DangerousSettingsButton
+ {
+ Text = MaintenanceSettingsStrings.ResetAllOffsets,
+ Action = () =>
+ {
+ dialogOverlay?.Push(new MassDeleteConfirmationDialog(() =>
+ {
+ resetOffsetsButton.Enabled.Value = false;
+ Task.Run(beatmaps.ResetAllOffsets).ContinueWith(_ => Schedule(() => resetOffsetsButton.Enabled.Value = true));
+ }, DeleteConfirmationContentStrings.Offsets));
+ }
+ });
+
AddRange(new Drawable[]
{
restoreButton = new SettingsButton