mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 20:33:35 +08:00
Ensure users cannot lose data when editing beatmaps above 10K (#37668)
Intends to close https://github.com/ppy/osu/issues/37395. In the past there have been many discussions about this dual stages wart. Whether it will continue to be "dual stages", or just a single stage with 12/14/16/18K, whether all of the skinning weirdness related to it (https://github.com/ppy/osu/issues/23620) will be supported, etc. This isn't that, I don't want to get into that, and I'm not promising anything. All I want to make sure here is that users cannot get their data lost by editing an existing >10K beatmap, and be understandably upset about it. To that end this mostly apes how stable does things.
This commit is contained in:
committed by
GitHub
Unverified
parent
9e20929ad3
commit
9d31332457
@@ -20,10 +20,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
||||
[Test]
|
||||
public void TestKeyCountChange()
|
||||
{
|
||||
FormSliderBar<float> keyCount = null!;
|
||||
FormSliderBar<int> keyCount = null!;
|
||||
|
||||
AddStep("go to setup screen", () => InputManager.Key(Key.F4));
|
||||
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<float>>().First(), () => Is.Not.Null);
|
||||
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<int>>().First(), () => Is.Not.Null);
|
||||
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
|
||||
AddStep("change key count to 8", () =>
|
||||
{
|
||||
@@ -41,5 +41,32 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
||||
AddStep("acquiesce", () => InputManager.Key(Key.Number1));
|
||||
AddUntilStep("beatmap became 8K", () => Game.Beatmap.Value.BeatmapInfo.Difficulty.CircleSize, () => Is.EqualTo(8));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDualStagesChange()
|
||||
{
|
||||
FormCheckBox dualStages = null!;
|
||||
FormSliderBar<int> keyCount = null!;
|
||||
|
||||
AddStep("go to setup screen", () => InputManager.Key(Key.F4));
|
||||
AddUntilStep("retrieve dual stages checkbox", () => dualStages = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormCheckBox>().First(), () => Is.Not.Null);
|
||||
AddUntilStep("retrieve key count slider", () => keyCount = Editor.ChildrenOfType<SetupScreen>().Single().ChildrenOfType<FormSliderBar<int>>().First(), () => Is.Not.Null);
|
||||
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
|
||||
AddStep("set dual stages", () =>
|
||||
{
|
||||
dualStages.Current.Value = true;
|
||||
});
|
||||
AddUntilStep("dialog visible", () => Game.ChildrenOfType<IDialogOverlay>().SingleOrDefault()?.CurrentDialog, Is.InstanceOf<SaveAndReloadEditorDialog>);
|
||||
AddStep("refuse", () => InputManager.Key(Key.Number2));
|
||||
AddAssert("key count is 5", () => keyCount.Current.Value, () => Is.EqualTo(5));
|
||||
|
||||
AddStep("set dual stages again", () =>
|
||||
{
|
||||
dualStages.Current.Value = true;
|
||||
});
|
||||
AddUntilStep("dialog visible", () => Game.ChildrenOfType<IDialogOverlay>().Single().CurrentDialog, Is.InstanceOf<SaveAndReloadEditorDialog>);
|
||||
AddStep("acquiesce", () => InputManager.Key(Key.Number1));
|
||||
AddUntilStep("beatmap became 12K", () => Game.Beatmap.Value.BeatmapInfo.Difficulty.CircleSize, () => Is.EqualTo(12));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
@@ -19,13 +20,22 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup
|
||||
{
|
||||
public override LocalisableString Title => EditorSetupStrings.DifficultyHeader;
|
||||
|
||||
private FormSliderBar<float> keyCountSlider { get; set; } = null!;
|
||||
private FormSliderBar<int> keyCountSlider { get; set; } = null!;
|
||||
private FormCheckBox dualStages { get; set; } = null!;
|
||||
private FormCheckBox specialStyle { get; set; } = null!;
|
||||
private FormSliderBar<float> healthDrainSlider { get; set; } = null!;
|
||||
private FormSliderBar<float> overallDifficultySlider { get; set; } = null!;
|
||||
private FormSliderBar<double> baseVelocitySlider { get; set; } = null!;
|
||||
private FormSliderBar<double> tickRateSlider { get; set; } = null!;
|
||||
|
||||
private readonly BindableInt singleStageKeyCount = new BindableInt
|
||||
{
|
||||
Default = (int)BeatmapDifficulty.DEFAULT_DIFFICULTY,
|
||||
Precision = 1,
|
||||
};
|
||||
|
||||
private readonly BindableInt actualKeyCount = new BindableInt();
|
||||
|
||||
[Resolved]
|
||||
private Editor? editor { get; set; }
|
||||
|
||||
@@ -37,20 +47,19 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
keyCountSlider = new FormSliderBar<float>
|
||||
keyCountSlider = new FormSliderBar<int>
|
||||
{
|
||||
Caption = BeatmapsetsStrings.ShowStatsCsMania,
|
||||
HintText = "The number of columns in the beatmap",
|
||||
Current = new BindableFloat(Beatmap.Difficulty.CircleSize)
|
||||
{
|
||||
Default = BeatmapDifficulty.DEFAULT_DIFFICULTY,
|
||||
MinValue = 0,
|
||||
MaxValue = 10,
|
||||
Precision = 1,
|
||||
},
|
||||
Current = singleStageKeyCount,
|
||||
TransferValueOnCommit = true,
|
||||
TabbableContentContainer = this,
|
||||
},
|
||||
dualStages = new FormCheckBox
|
||||
{
|
||||
Caption = "Dual stages",
|
||||
HintText = "Doubles the number of keys by adding a second stage."
|
||||
},
|
||||
specialStyle = new FormCheckBox
|
||||
{
|
||||
Caption = "Use special (N+1) style",
|
||||
@@ -117,16 +126,54 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup
|
||||
},
|
||||
};
|
||||
|
||||
keyCountSlider.Current.BindValueChanged(updateKeyCount);
|
||||
setStateFromActualKeyCount((int)Beatmap.Difficulty.CircleSize);
|
||||
|
||||
keyCountSlider.Current.BindValueChanged(_ => calculateActualKeyCount());
|
||||
dualStages.Current.BindValueChanged(_ =>
|
||||
{
|
||||
updateSingleStageKeyCountBounds();
|
||||
calculateActualKeyCount();
|
||||
});
|
||||
actualKeyCount.BindValueChanged(updateKeyCount);
|
||||
|
||||
healthDrainSlider.Current.BindValueChanged(_ => updateValues());
|
||||
overallDifficultySlider.Current.BindValueChanged(_ => updateValues());
|
||||
baseVelocitySlider.Current.BindValueChanged(_ => updateValues());
|
||||
tickRateSlider.Current.BindValueChanged(_ => updateValues());
|
||||
}
|
||||
|
||||
private void updateSingleStageKeyCountBounds()
|
||||
{
|
||||
singleStageKeyCount.MinValue = dualStages.Current.Value ? ManiaRuleset.MAX_STAGE_KEYS / 2 + 1 : 1;
|
||||
singleStageKeyCount.MaxValue = dualStages.Current.Value ? LegacyBeatmapDecoder.MAX_MANIA_KEY_COUNT / 2 : ManiaRuleset.MAX_STAGE_KEYS;
|
||||
}
|
||||
|
||||
private void setStateFromActualKeyCount(int keyCount)
|
||||
{
|
||||
actualKeyCount.Value = keyCount;
|
||||
|
||||
if (keyCount > 10)
|
||||
{
|
||||
dualStages.Current.Value = true;
|
||||
singleStageKeyCount.Value = keyCount / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dualStages.Current.Value = false;
|
||||
singleStageKeyCount.Value = keyCount;
|
||||
}
|
||||
|
||||
updateSingleStageKeyCountBounds();
|
||||
}
|
||||
|
||||
private void calculateActualKeyCount()
|
||||
{
|
||||
actualKeyCount.Value = keyCountSlider.Current.Value * (dualStages.Current.Value ? 2 : 1);
|
||||
}
|
||||
|
||||
private bool updatingKeyCount;
|
||||
|
||||
private void updateKeyCount(ValueChangedEvent<float> keyCount)
|
||||
private void updateKeyCount(ValueChangedEvent<int> keyCount)
|
||||
{
|
||||
if (updatingKeyCount) return;
|
||||
|
||||
@@ -143,7 +190,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup
|
||||
Schedule(() =>
|
||||
{
|
||||
changeHandler!.RestoreState(-1);
|
||||
Beatmap.Difficulty.CircleSize = keyCountSlider.Current.Value = keyCount.OldValue;
|
||||
Beatmap.Difficulty.CircleSize = keyCount.OldValue;
|
||||
setStateFromActualKeyCount(keyCount.OldValue);
|
||||
updatingKeyCount = false;
|
||||
});
|
||||
}
|
||||
@@ -158,7 +206,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup
|
||||
{
|
||||
// for now, update these on commit rather than making BeatmapMetadata bindables.
|
||||
// after switching database engines we can reconsider if switching to bindables is a good direction.
|
||||
Beatmap.Difficulty.CircleSize = keyCountSlider.Current.Value;
|
||||
Beatmap.Difficulty.CircleSize = actualKeyCount.Value;
|
||||
Beatmap.SpecialStyle = specialStyle.Current.Value;
|
||||
Beatmap.Difficulty.DrainRate = healthDrainSlider.Current.Value;
|
||||
Beatmap.Difficulty.OverallDifficulty = overallDifficultySlider.Current.Value;
|
||||
|
||||
Reference in New Issue
Block a user