1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Merge pull request #7175 from LeNitrous/update-beatmap-settings

Display current difficulty statistics with mods applied
This commit is contained in:
Dean Herbert 2019-12-18 18:43:49 +09:00 committed by GitHub
commit 36172cf2bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 151 additions and 26 deletions

View File

@ -8,6 +8,9 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play.HUD;
using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps;
using osuTK;
@ -20,8 +23,10 @@ namespace osu.Game.Tests.Visual.SongSelect
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BeatmapDetails) };
private ModDisplay modDisplay;
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
private void load(OsuGameBase game, RulesetStore rulesets)
{
BeatmapDetailArea detailsArea;
Add(detailsArea = new BeatmapDetailArea
@ -31,6 +36,16 @@ namespace osu.Game.Tests.Visual.SongSelect
Size = new Vector2(550f, 450f),
});
Add(modDisplay = new ModDisplay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Position = new Vector2(0, 25),
});
modDisplay.Current.BindTo(SelectedMods);
AddStep("all metrics", () => detailsArea.Beatmap = new TestWorkingBeatmap(new Beatmap
{
BeatmapInfo =
@ -163,6 +178,60 @@ namespace osu.Game.Tests.Visual.SongSelect
}));
AddStep("null beatmap", () => detailsArea.Beatmap = null);
Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance();
AddStep("with EZ mod", () =>
{
detailsArea.Beatmap = new TestWorkingBeatmap(new Beatmap
{
BeatmapInfo =
{
Version = "Has Easy Mod",
Metadata = new BeatmapMetadata
{
Source = "osu!lazer",
Tags = "this beatmap has the easy mod enabled",
},
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 3,
DrainRate = 3,
OverallDifficulty = 3,
ApproachRate = 3,
},
StarDifficulty = 1f,
}
});
SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) };
});
AddStep("with HR mod", () =>
{
detailsArea.Beatmap = new TestWorkingBeatmap(new Beatmap
{
BeatmapInfo =
{
Version = "Has Hard Rock Mod",
Metadata = new BeatmapMetadata
{
Source = "osu!lazer",
Tags = "this beatmap has the hard rock mod enabled",
},
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 3,
DrainRate = 3,
OverallDifficulty = 3,
ApproachRate = 3,
},
StarDifficulty = 1f,
}
});
SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) };
});
}
}
}

View File

@ -12,11 +12,18 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System;
using osu.Game.Beatmaps;
using osu.Framework.Bindables;
using System.Collections.Generic;
using osu.Game.Rulesets.Mods;
using System.Linq;
namespace osu.Game.Screens.Select.Details
{
public class AdvancedStats : Container
{
[Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty;
private BeatmapInfo beatmap;
@ -30,22 +37,7 @@ namespace osu.Game.Screens.Select.Details
beatmap = value;
//mania specific
if ((Beatmap?.Ruleset?.ID ?? 0) == 3)
{
firstValue.Title = "Key Amount";
firstValue.Value = (int)MathF.Round(Beatmap?.BaseDifficulty?.CircleSize ?? 0);
}
else
{
firstValue.Title = "Circle Size";
firstValue.Value = Beatmap?.BaseDifficulty?.CircleSize ?? 0;
}
hpDrain.Value = Beatmap?.BaseDifficulty?.DrainRate ?? 0;
accuracy.Value = Beatmap?.BaseDifficulty?.OverallDifficulty ?? 0;
approachRate.Value = Beatmap?.BaseDifficulty?.ApproachRate ?? 0;
starDifficulty.Value = (float)(Beatmap?.StarDifficulty ?? 0);
updateStatistics();
}
}
@ -73,6 +65,45 @@ namespace osu.Game.Screens.Select.Details
starDifficulty.AccentColour = colours.Yellow;
}
protected override void LoadComplete()
{
base.LoadComplete();
mods.BindValueChanged(_ => updateStatistics(), true);
}
private void updateStatistics()
{
BeatmapDifficulty baseDifficulty = Beatmap?.BaseDifficulty;
BeatmapDifficulty adjustedDifficulty = null;
if (baseDifficulty != null && mods.Value.Any(m => m is IApplicableToDifficulty))
{
adjustedDifficulty = baseDifficulty.Clone();
foreach (var mod in mods.Value.OfType<IApplicableToDifficulty>())
mod.ApplyToDifficulty(adjustedDifficulty);
}
//mania specific
if ((Beatmap?.Ruleset?.ID ?? 0) == 3)
{
firstValue.Title = "Key Amount";
firstValue.Value = ((int)MathF.Round(baseDifficulty?.CircleSize ?? 0), (int)MathF.Round(adjustedDifficulty?.CircleSize ?? 0));
}
else
{
firstValue.Title = "Circle Size";
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
}
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
}
private class StatisticRow : Container, IHasAccentColour
{
private const float value_width = 25;
@ -80,8 +111,11 @@ namespace osu.Game.Screens.Select.Details
private readonly float maxValue;
private readonly bool forceDecimalPlaces;
private readonly OsuSpriteText name, value;
private readonly Bar bar;
private readonly OsuSpriteText name, valueText;
private readonly Bar bar, modBar;
[Resolved]
private OsuColour colours { get; set; }
public string Title
{
@ -89,16 +123,29 @@ namespace osu.Game.Screens.Select.Details
set => name.Text = value;
}
private float difficultyValue;
private (float baseValue, float? adjustedValue) value;
public float Value
public (float baseValue, float? adjustedValue) Value
{
get => difficultyValue;
get => value;
set
{
difficultyValue = value;
bar.Length = value / maxValue;
this.value.Text = value.ToString(forceDecimalPlaces ? "0.00" : "0.##");
if (value == this.value)
return;
this.value = value;
bar.Length = value.baseValue / maxValue;
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
modBar.Length = (value.adjustedValue ?? 0) / maxValue;
if (value.adjustedValue > value.baseValue)
modBar.AccentColour = valueText.Colour = colours.Red;
else if (value.adjustedValue < value.baseValue)
modBar.AccentColour = valueText.Colour = colours.BlueDark;
else
modBar.AccentColour = valueText.Colour = Color4.White;
}
}
@ -135,13 +182,22 @@ namespace osu.Game.Screens.Select.Details
BackgroundColour = Color4.White.Opacity(0.5f),
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
},
modBar = new Bar
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
RelativeSizeAxes = Axes.X,
Alpha = 0.5f,
Height = 5,
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
},
new Container
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Width = value_width,
RelativeSizeAxes = Axes.Y,
Child = value = new OsuSpriteText
Child = valueText = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,