1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-17 04:32:53 +08:00

Merge branch 'master' into adjust-profile-scores

This commit is contained in:
recapitalverb 2020-02-02 21:14:20 +07:00 committed by GitHub
commit 2a463e2893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 199 additions and 49 deletions

View File

@ -0,0 +1,175 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Select.Details;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.SongSelect
{
[System.ComponentModel.Description("Advanced beatmap statistics display")]
public class TestSceneAdvancedStats : OsuTestScene
{
private TestAdvancedStats advancedStats;
[Resolved]
private RulesetStore rulesets { get; set; }
[Resolved]
private OsuColour colours { get; set; }
[SetUp]
public void Setup() => Schedule(() => Child = advancedStats = new TestAdvancedStats
{
Width = 500
});
private BeatmapInfo exampleBeatmapInfo => new BeatmapInfo
{
RulesetID = 0,
Ruleset = rulesets.AvailableRulesets.First(),
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 7.2f,
DrainRate = 3,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f
},
StarDifficulty = 4.5f
};
[Test]
public void TestNoMod()
{
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
AddStep("no mods selected", () => SelectedMods.Value = Array.Empty<Mod>());
AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Circle Size");
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
}
[Test]
public void TestManiaFirstBarText()
{
AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo
{
Ruleset = rulesets.GetRuleset(3),
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 5,
DrainRate = 4.3f,
OverallDifficulty = 4.5f,
ApproachRate = 3.1f
},
StarDifficulty = 8
});
AddAssert("first bar text is Key Count", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Key Count");
}
[Test]
public void TestEasyMod()
{
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
AddStep("select EZ mod", () =>
{
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModEasy>().Single() };
});
AddAssert("circle size bar is blue", () => barIsBlue(advancedStats.FirstValue));
AddAssert("HP drain bar is blue", () => barIsBlue(advancedStats.HpDrain));
AddAssert("accuracy bar is blue", () => barIsBlue(advancedStats.Accuracy));
AddAssert("approach rate bar is blue", () => barIsBlue(advancedStats.ApproachRate));
}
[Test]
public void TestHardRockMod()
{
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
AddStep("select HR mod", () =>
{
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModHardRock>().Single() };
});
AddAssert("circle size bar is red", () => barIsRed(advancedStats.FirstValue));
AddAssert("HP drain bar is red", () => barIsRed(advancedStats.HpDrain));
AddAssert("accuracy bar is red", () => barIsRed(advancedStats.Accuracy));
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
}
[Test]
public void TestUnchangedDifficultyAdjustMod()
{
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
AddStep("select unchanged Difficulty Adjust mod", () =>
{
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().Single();
difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty);
SelectedMods.Value = new[] { difficultyAdjustMod };
});
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
}
[Test]
public void TestChangedDifficultyAdjustMod()
{
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
AddStep("select changed Difficulty Adjust mod", () =>
{
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().Single();
var originalDifficulty = advancedStats.Beatmap.BaseDifficulty;
var adjustedDifficulty = new BeatmapDifficulty
{
CircleSize = originalDifficulty.CircleSize,
DrainRate = originalDifficulty.DrainRate - 0.5f,
OverallDifficulty = originalDifficulty.OverallDifficulty,
ApproachRate = originalDifficulty.ApproachRate + 2.2f,
};
difficultyAdjustMod.ReadFromDifficulty(adjustedDifficulty);
SelectedMods.Value = new[] { difficultyAdjustMod };
});
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
AddAssert("drain rate bar is blue", () => barIsBlue(advancedStats.HpDrain));
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
}
private bool barIsWhite(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == Color4.White;
private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark;
private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red;
private class TestAdvancedStats : AdvancedStats
{
public new StatisticRow FirstValue => base.FirstValue;
public new StatisticRow HpDrain => base.HpDrain;
public new StatisticRow Accuracy => base.Accuracy;
public new StatisticRow ApproachRate => base.ApproachRate;
}
}
}

View File

@ -3,14 +3,8 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
namespace osu.Game.Tests.Visual.SongSelect namespace osu.Game.Tests.Visual.SongSelect
@ -180,27 +174,5 @@ namespace osu.Game.Tests.Visual.SongSelect
OnlineBeatmapID = 162, OnlineBeatmapID = 162,
}); });
} }
[Resolved]
private RulesetStore rulesets { get; set; }
[Resolved]
private OsuColour colours { get; set; }
[Test]
public void TestModAdjustments()
{
TestAllMetrics();
Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance();
AddStep("with EZ mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) });
AddAssert("first bar coloured blue", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.BlueDark);
AddStep("with HR mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) });
AddAssert("first bar coloured red", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.Red);
}
} }
} }

View File

@ -16,6 +16,7 @@ using System.Collections.Generic;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using System.Linq; using System.Linq;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Framework.Utils;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
@ -26,7 +27,8 @@ namespace osu.Game.Screens.Select.Details
[Resolved] [Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; } private IBindable<IReadOnlyList<Mod>> mods { get; set; }
private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate;
private readonly StatisticRow starDifficulty;
private BeatmapInfo beatmap; private BeatmapInfo beatmap;
@ -52,10 +54,10 @@ namespace osu.Game.Screens.Select.Details
Spacing = new Vector2(4f), Spacing = new Vector2(4f),
Children = new[] Children = new[]
{ {
firstValue = new StatisticRow(), //circle size/key amount FirstValue = new StatisticRow(), //circle size/key amount
hpDrain = new StatisticRow { Title = "HP Drain" }, HpDrain = new StatisticRow { Title = "HP Drain" },
accuracy = new StatisticRow { Title = "Accuracy" }, Accuracy = new StatisticRow { Title = "Accuracy" },
approachRate = new StatisticRow { Title = "Approach Rate" }, ApproachRate = new StatisticRow { Title = "Approach Rate" },
starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" }, starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
}, },
}; };
@ -122,24 +124,24 @@ namespace osu.Game.Screens.Select.Details
case 3: case 3:
// Account for mania differences locally for now // Account for mania differences locally for now
// Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes // Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
firstValue.Title = "Key Count"; FirstValue.Title = "Key Count";
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null); FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
break; break;
default: default:
firstValue.Title = "Circle Size"; FirstValue.Title = "Circle Size";
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
break; break;
} }
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null); starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate); HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty); Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate); ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
} }
private class StatisticRow : Container, IHasAccentColour public class StatisticRow : Container, IHasAccentColour
{ {
private const float value_width = 25; private const float value_width = 25;
private const float name_width = 70; private const float name_width = 70;
@ -147,7 +149,8 @@ namespace osu.Game.Screens.Select.Details
private readonly float maxValue; private readonly float maxValue;
private readonly bool forceDecimalPlaces; private readonly bool forceDecimalPlaces;
private readonly OsuSpriteText name, valueText; private readonly OsuSpriteText name, valueText;
private readonly Bar bar, modBar; private readonly Bar bar;
public readonly Bar ModBar;
[Resolved] [Resolved]
private OsuColour colours { get; set; } private OsuColour colours { get; set; }
@ -173,14 +176,14 @@ namespace osu.Game.Screens.Select.Details
bar.Length = value.baseValue / maxValue; bar.Length = value.baseValue / maxValue;
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##"); valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
modBar.Length = (value.adjustedValue ?? 0) / maxValue; ModBar.Length = (value.adjustedValue ?? 0) / maxValue;
if (value.adjustedValue > value.baseValue) if (Precision.AlmostEquals(value.baseValue, value.adjustedValue ?? value.baseValue, 0.05f))
modBar.AccentColour = valueText.Colour = colours.Red; ModBar.AccentColour = valueText.Colour = Color4.White;
else if (value.adjustedValue > value.baseValue)
ModBar.AccentColour = valueText.Colour = colours.Red;
else if (value.adjustedValue < value.baseValue) else if (value.adjustedValue < value.baseValue)
modBar.AccentColour = valueText.Colour = colours.BlueDark; ModBar.AccentColour = valueText.Colour = colours.BlueDark;
else
modBar.AccentColour = valueText.Colour = Color4.White;
} }
} }
@ -217,7 +220,7 @@ namespace osu.Game.Screens.Select.Details
BackgroundColour = Color4.White.Opacity(0.5f), BackgroundColour = Color4.White.Opacity(0.5f),
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 }, Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
}, },
modBar = new Bar ModBar = new Bar
{ {
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,