mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 13:37:25 +08:00
Merge pull request #23431 from peppy/base-s-v
Add beatmap-level velocity setting to difficulty settings
This commit is contained in:
commit
e85afeb3f7
@ -34,7 +34,8 @@ namespace osu.Game.Beatmaps
|
||||
float ApproachRate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The slider multiplier of the associated beatmap.
|
||||
/// The base slider velocity of the associated beatmap.
|
||||
/// This was known as "SliderMultiplier" in the .osu format and stable editor.
|
||||
/// </summary>
|
||||
double SliderMultiplier { get; }
|
||||
|
||||
|
@ -126,6 +126,16 @@ namespace osu.Game.Localisation
|
||||
public static LocalisableString OverallDifficultyDescription =>
|
||||
new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)");
|
||||
|
||||
/// <summary>
|
||||
/// "Base Velocity"
|
||||
/// </summary>
|
||||
public static LocalisableString BaseVelocity => new TranslatableString(getKey(@"base_velocity"), @"Base Velocity");
|
||||
|
||||
/// <summary>
|
||||
/// "The base velocity of the beatmap, affecting things like slider velocity and scroll speed in some rulesets."
|
||||
/// </summary>
|
||||
public static LocalisableString BaseVelocityDescription => new TranslatableString(getKey(@"base_velocity_description"), @"The base velocity of the beatmap, affecting things like slider velocity and scroll speed in some rulesets.");
|
||||
|
||||
/// <summary>
|
||||
/// "Metadata"
|
||||
/// </summary>
|
||||
|
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
if (selected is IHasSliderVelocity sliderVelocity)
|
||||
{
|
||||
AddHeader("Slider Velocity");
|
||||
AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x");
|
||||
AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x ({sliderVelocity.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier:#,0.00}x)");
|
||||
}
|
||||
|
||||
if (selected is IHasRepeats repeats)
|
||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = "Hold shift while dragging the end of an object to adjust velocity while snapping."
|
||||
},
|
||||
new SliderVelocityInspector(),
|
||||
new SliderVelocityInspector(sliderVelocitySlider.Current),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -145,34 +145,48 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
internal partial class SliderVelocityInspector : EditorInspector
|
||||
{
|
||||
private readonly Bindable<double?> current;
|
||||
|
||||
public SliderVelocityInspector(Bindable<double?> current)
|
||||
{
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
EditorBeatmap.TransactionBegan += updateInspectorText;
|
||||
EditorBeatmap.TransactionEnded += updateInspectorText;
|
||||
EditorBeatmap.BeatmapReprocessed += updateInspectorText;
|
||||
current.ValueChanged += _ => updateInspectorText();
|
||||
|
||||
updateInspectorText();
|
||||
}
|
||||
|
||||
private void updateInspectorText()
|
||||
{
|
||||
double beatmapVelocity = EditorBeatmap.Difficulty.SliderMultiplier;
|
||||
|
||||
InspectorText.Clear();
|
||||
|
||||
double[] sliderVelocities = EditorBeatmap.HitObjects.OfType<IHasSliderVelocity>().Select(sv => sv.SliderVelocity).OrderBy(v => v).ToArray();
|
||||
|
||||
if (sliderVelocities.Length < 2)
|
||||
return;
|
||||
AddHeader("Base velocity (from beatmap setup)");
|
||||
AddValue($"{beatmapVelocity:#,0.00}x");
|
||||
|
||||
double? modeSliderVelocity = sliderVelocities.GroupBy(v => v).MaxBy(v => v.Count())?.Key;
|
||||
double? medianSliderVelocity = sliderVelocities[sliderVelocities.Length / 2];
|
||||
AddHeader("Final velocity");
|
||||
AddValue($"{beatmapVelocity * current.Value:#,0.00}x");
|
||||
|
||||
AddHeader("Average velocity");
|
||||
AddValue($"{medianSliderVelocity:#,0.00}x");
|
||||
if (sliderVelocities.First() != sliderVelocities.Last())
|
||||
{
|
||||
AddHeader("Beatmap velocity range");
|
||||
|
||||
AddHeader("Most used velocity");
|
||||
AddValue($"{modeSliderVelocity:#,0.00}x");
|
||||
string range = $"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x";
|
||||
if (beatmapVelocity != 1)
|
||||
range += $" ({beatmapVelocity * sliderVelocities.First():#,0.00}x - {beatmapVelocity * sliderVelocities.Last():#,0.00}x)";
|
||||
|
||||
AddHeader("Velocity range");
|
||||
AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x");
|
||||
AddValue(range);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
@ -181,6 +195,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
EditorBeatmap.TransactionBegan -= updateInspectorText;
|
||||
EditorBeatmap.TransactionEnded -= updateInspectorText;
|
||||
EditorBeatmap.BeatmapReprocessed -= updateInspectorText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
private LabelledSliderBar<float> healthDrainSlider = null!;
|
||||
private LabelledSliderBar<float> approachRateSlider = null!;
|
||||
private LabelledSliderBar<float> overallDifficultySlider = null!;
|
||||
private LabelledSliderBar<double> baseVelocitySlider = null!;
|
||||
|
||||
public override LocalisableString Title => EditorSetupStrings.DifficultyHeader;
|
||||
|
||||
@ -79,13 +80,29 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
Precision = 0.1f,
|
||||
}
|
||||
},
|
||||
baseVelocitySlider = new LabelledSliderBar<double>
|
||||
{
|
||||
Label = EditorSetupStrings.BaseVelocity,
|
||||
FixedLabelWidth = LABEL_WIDTH,
|
||||
Description = EditorSetupStrings.BaseVelocityDescription,
|
||||
Current = new BindableDouble(Beatmap.Difficulty.SliderMultiplier)
|
||||
{
|
||||
Default = 1,
|
||||
MinValue = 0.4,
|
||||
MaxValue = 3.6,
|
||||
Precision = 0.01f,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
foreach (var item in Children.OfType<LabelledSliderBar<float>>())
|
||||
item.Current.ValueChanged += onValueChanged;
|
||||
item.Current.ValueChanged += _ => updateValues();
|
||||
|
||||
foreach (var item in Children.OfType<LabelledSliderBar<double>>())
|
||||
item.Current.ValueChanged += _ => updateValues();
|
||||
}
|
||||
|
||||
private void onValueChanged(ValueChangedEvent<float> args)
|
||||
private void updateValues()
|
||||
{
|
||||
// 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.
|
||||
@ -93,6 +110,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
Beatmap.Difficulty.DrainRate = healthDrainSlider.Current.Value;
|
||||
Beatmap.Difficulty.ApproachRate = approachRateSlider.Current.Value;
|
||||
Beatmap.Difficulty.OverallDifficulty = overallDifficultySlider.Current.Value;
|
||||
Beatmap.Difficulty.SliderMultiplier = baseVelocitySlider.Current.Value;
|
||||
|
||||
Beatmap.UpdateAllHitObjects();
|
||||
Beatmap.SaveState();
|
||||
|
Loading…
Reference in New Issue
Block a user