mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 06:05:07 +08:00
Merge pull request #14355 from frenzibyte/mod-settings-difficulty-cache
Update star difficulty bindables on mod settings change
This commit is contained in:
commit
2b0f2a6db9
34
osu.Game.Benchmarks/BenchmarkMod.cs
Normal file
34
osu.Game.Benchmarks/BenchmarkMod.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// 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 BenchmarkDotNet.Attributes;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
public class BenchmarkMod : BenchmarkTest
|
||||||
|
{
|
||||||
|
private OsuModDoubleTime mod;
|
||||||
|
|
||||||
|
[Params(1, 10, 100)]
|
||||||
|
public int Times { get; set; }
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void GlobalSetup()
|
||||||
|
{
|
||||||
|
mod = new OsuModDoubleTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int ModHashCode()
|
||||||
|
{
|
||||||
|
var hashCode = new HashCode();
|
||||||
|
|
||||||
|
for (int i = 0; i < Times; i++)
|
||||||
|
hashCode.Add(mod);
|
||||||
|
|
||||||
|
return hashCode.ToHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
// 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 NUnit.Framework;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Beatmaps
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class BeatmapDifficultyCacheTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestKeyEqualsWithDifferentModInstances()
|
|
||||||
{
|
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
|
|
||||||
Assert.That(key1, Is.EqualTo(key2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestKeyEqualsWithDifferentModOrder()
|
|
||||||
{
|
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
|
||||||
|
|
||||||
Assert.That(key1, Is.EqualTo(key2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(1.3, DifficultyRating.Easy)]
|
|
||||||
[TestCase(1.993, DifficultyRating.Easy)]
|
|
||||||
[TestCase(1.998, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.4, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.693, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.698, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.5, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.993, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.997, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.0, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.292, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.297, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.2, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.493, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.498, DifficultyRating.ExpertPlus)]
|
|
||||||
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
|
||||||
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
|
||||||
{
|
|
||||||
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
|
|
||||||
|
|
||||||
Assert.AreEqual(expectedBracket, actualBracket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
158
osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
Normal file
158
osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Beatmaps
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class TestSceneBeatmapDifficultyCache : OsuTestScene
|
||||||
|
{
|
||||||
|
public const double BASE_STARS = 5.55;
|
||||||
|
|
||||||
|
private BeatmapSetInfo importedSet;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
private TestBeatmapDifficultyCache difficultyCache;
|
||||||
|
|
||||||
|
private IBindable<StarDifficulty?> starDifficultyBindable;
|
||||||
|
private Queue<ValueChangedEvent<StarDifficulty?>> starDifficultyChangesQueue;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuGameBase osu)
|
||||||
|
{
|
||||||
|
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("setup difficulty cache", () =>
|
||||||
|
{
|
||||||
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
|
|
||||||
|
Child = difficultyCache = new TestBeatmapDifficultyCache();
|
||||||
|
|
||||||
|
starDifficultyChangesQueue = new Queue<ValueChangedEvent<StarDifficulty?>>();
|
||||||
|
starDifficultyBindable = difficultyCache.GetBindableDifficulty(importedSet.Beatmaps.First());
|
||||||
|
starDifficultyBindable.BindValueChanged(starDifficultyChangesQueue.Enqueue);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert($"star difficulty -> {BASE_STARS}", () =>
|
||||||
|
starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS &&
|
||||||
|
starDifficultyChangesQueue.Count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStarDifficultyChangesOnModSettings()
|
||||||
|
{
|
||||||
|
OsuModDoubleTime dt = null;
|
||||||
|
|
||||||
|
AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } });
|
||||||
|
AddAssert($"star difficulty -> {BASE_STARS + 1.5}", () =>
|
||||||
|
starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.5 &&
|
||||||
|
starDifficultyChangesQueue.Count == 0);
|
||||||
|
|
||||||
|
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25);
|
||||||
|
AddAssert($"star difficulty -> {BASE_STARS + 1.25}", () =>
|
||||||
|
starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.25 &&
|
||||||
|
starDifficultyChangesQueue.Count == 0);
|
||||||
|
|
||||||
|
AddStep("change selected mod to NC", () => SelectedMods.Value = new[] { new OsuModNightcore { SpeedChange = { Value = 1.75 } } });
|
||||||
|
AddAssert($"star difficulty -> {BASE_STARS + 1.75}", () =>
|
||||||
|
starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.75 &&
|
||||||
|
starDifficultyChangesQueue.Count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualsWithDifferentModInstances()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualsWithDifferentModOrder()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyDoesntEqualWithDifferentModSettings()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.Not.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualWithMatchingModSettings()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1.3, DifficultyRating.Easy)]
|
||||||
|
[TestCase(1.993, DifficultyRating.Easy)]
|
||||||
|
[TestCase(1.998, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.4, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.693, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.698, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.5, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.993, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.997, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.0, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.292, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.297, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.2, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.493, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.498, DifficultyRating.ExpertPlus)]
|
||||||
|
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
||||||
|
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
||||||
|
{
|
||||||
|
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
|
||||||
|
|
||||||
|
Assert.AreEqual(expectedBracket, actualBracket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestBeatmapDifficultyCache : BeatmapDifficultyCache
|
||||||
|
{
|
||||||
|
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var rateAdjust = lookup.OrderedMods.OfType<ModRateAdjust>().SingleOrDefault();
|
||||||
|
if (rateAdjust != null)
|
||||||
|
return Task.FromResult(new StarDifficulty(BASE_STARS + rateAdjust.SpeedChange.Value, 0));
|
||||||
|
|
||||||
|
return Task.FromResult(new StarDifficulty(BASE_STARS, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -65,6 +66,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("show", () => { infoWedge.Show(); });
|
AddStep("show", () => { infoWedge.Show(); });
|
||||||
|
|
||||||
|
AddSliderStep("change star difficulty", 0, 11.9, 5.55, v =>
|
||||||
|
{
|
||||||
|
foreach (var hasCurrentValue in infoWedge.Info.ChildrenOfType<IHasCurrentValue<StarDifficulty>>())
|
||||||
|
hasCurrentValue.Current.Value = new StarDifficulty(v, 0);
|
||||||
|
});
|
||||||
|
|
||||||
foreach (var rulesetInfo in rulesets.AvailableRulesets)
|
foreach (var rulesetInfo in rulesets.AvailableRulesets)
|
||||||
{
|
{
|
||||||
var instance = rulesetInfo.CreateInstance();
|
var instance = rulesetInfo.CreateInstance();
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
@ -50,32 +49,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
StarRatingDisplay starRating = null;
|
StarRatingDisplay starRating = null;
|
||||||
|
|
||||||
BindableDouble starRatingNumeric;
|
AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1), animated: true)
|
||||||
|
|
||||||
AddStep("load display", () =>
|
|
||||||
{
|
|
||||||
Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1))
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Scale = new Vector2(3f),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("transform over spectrum", () =>
|
|
||||||
{
|
|
||||||
starRatingNumeric = new BindableDouble();
|
|
||||||
starRatingNumeric.BindValueChanged(val => starRating.Current.Value = new StarDifficulty(val.NewValue, 1));
|
|
||||||
this.TransformBindableTo(starRatingNumeric, 10, 10000, Easing.OutQuint);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestChangingStarRatingDisplay()
|
|
||||||
{
|
|
||||||
StarRatingDisplay starRating = null;
|
|
||||||
|
|
||||||
AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1))
|
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -14,6 +14,7 @@ using osu.Framework.Lists;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -56,12 +57,28 @@ namespace osu.Game.Beatmaps
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; }
|
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; }
|
||||||
|
|
||||||
|
private ModSettingChangeTracker modSettingChangeTracker;
|
||||||
|
private ScheduledDelegate debouncedModSettingsChange;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
currentRuleset.BindValueChanged(_ => updateTrackedBindables());
|
currentRuleset.BindValueChanged(_ => updateTrackedBindables());
|
||||||
currentMods.BindValueChanged(_ => updateTrackedBindables(), true);
|
|
||||||
|
currentMods.BindValueChanged(mods =>
|
||||||
|
{
|
||||||
|
modSettingChangeTracker?.Dispose();
|
||||||
|
|
||||||
|
updateTrackedBindables();
|
||||||
|
|
||||||
|
modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue);
|
||||||
|
modSettingChangeTracker.SettingChanged += _ =>
|
||||||
|
{
|
||||||
|
debouncedModSettingsChange?.Cancel();
|
||||||
|
debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100);
|
||||||
|
};
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -84,7 +101,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
/// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The bindable will not update to follow the currently-selected ruleset and mods.
|
/// The bindable will not update to follow the currently-selected ruleset and mods or its settings.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
||||||
@ -275,6 +292,8 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
modSettingChangeTracker?.Dispose();
|
||||||
|
|
||||||
cancelTrackedBindableUpdate();
|
cancelTrackedBindableUpdate();
|
||||||
updateScheduler?.Dispose();
|
updateScheduler?.Dispose();
|
||||||
}
|
}
|
||||||
@ -297,7 +316,7 @@ namespace osu.Game.Beatmaps
|
|||||||
public bool Equals(DifficultyCacheLookup other)
|
public bool Equals(DifficultyCacheLookup other)
|
||||||
=> Beatmap.ID == other.Beatmap.ID
|
=> Beatmap.ID == other.Beatmap.ID
|
||||||
&& Ruleset.ID == other.Ruleset.ID
|
&& Ruleset.ID == other.Ruleset.ID
|
||||||
&& OrderedMods.Select(m => m.Acronym).SequenceEqual(other.OrderedMods.Select(m => m.Acronym));
|
&& OrderedMods.SequenceEqual(other.OrderedMods);
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
@ -307,7 +326,7 @@ namespace osu.Game.Beatmaps
|
|||||||
hashCode.Add(Ruleset.ID);
|
hashCode.Add(Ruleset.ID);
|
||||||
|
|
||||||
foreach (var mod in OrderedMods)
|
foreach (var mod in OrderedMods)
|
||||||
hashCode.Add(mod.Acronym);
|
hashCode.Add(mod);
|
||||||
|
|
||||||
return hashCode.ToHashCode();
|
return hashCode.ToHashCode();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
@ -22,6 +23,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty>
|
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty>
|
||||||
{
|
{
|
||||||
|
private readonly bool animated;
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly SpriteIcon starIcon;
|
private readonly SpriteIcon starIcon;
|
||||||
private readonly OsuSpriteText starsText;
|
private readonly OsuSpriteText starsText;
|
||||||
@ -34,6 +36,14 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
set => current.Current = value;
|
set => current.Current = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly Bindable<double> displayedStars = new BindableDouble();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently displayed stars of this display wrapped in a bindable.
|
||||||
|
/// This bindable gets transformed on change rather than instantaneous, if animation is enabled.
|
||||||
|
/// </summary>
|
||||||
|
public IBindable<double> DisplayedStars => displayedStars;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
@ -45,8 +55,11 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="starDifficulty">The already computed <see cref="StarDifficulty"/> to display.</param>
|
/// <param name="starDifficulty">The already computed <see cref="StarDifficulty"/> to display.</param>
|
||||||
/// <param name="size">The size of the star rating display.</param>
|
/// <param name="size">The size of the star rating display.</param>
|
||||||
public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular)
|
/// <param name="animated">Whether the star rating display will perform transforms on change rather than updating instantaneously.</param>
|
||||||
|
public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular, bool animated = false)
|
||||||
{
|
{
|
||||||
|
this.animated = animated;
|
||||||
|
|
||||||
Current.Value = starDifficulty;
|
Current.Value = starDifficulty;
|
||||||
|
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
@ -112,7 +125,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
// see https://github.com/ppy/osu-framework/issues/3271.
|
// see https://github.com/ppy/osu-framework/issues/3271.
|
||||||
Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold),
|
Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold),
|
||||||
Shadow = false,
|
Shadow = false,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -126,12 +139,22 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
Current.BindValueChanged(c =>
|
Current.BindValueChanged(c =>
|
||||||
{
|
{
|
||||||
starsText.Text = c.NewValue.Stars.ToString("0.00");
|
if (animated)
|
||||||
|
this.TransformBindableTo(displayedStars, c.NewValue.Stars, 750, Easing.OutQuint);
|
||||||
|
else
|
||||||
|
displayedStars.Value = c.NewValue.Stars;
|
||||||
|
});
|
||||||
|
|
||||||
background.Colour = colours.ForStarDifficulty(c.NewValue.Stars);
|
displayedStars.Value = Current.Value.Stars;
|
||||||
|
|
||||||
starIcon.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47");
|
displayedStars.BindValueChanged(s =>
|
||||||
starsText.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f);
|
{
|
||||||
|
starsText.Text = s.NewValue.ToLocalisableString("0.00");
|
||||||
|
|
||||||
|
background.Colour = colours.ForStarDifficulty(s.NewValue);
|
||||||
|
|
||||||
|
starIcon.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47");
|
||||||
|
starsText.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f);
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,17 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual Type[] IncompatibleMods => Array.Empty<Type>();
|
public virtual Type[] IncompatibleMods => Array.Empty<Type>();
|
||||||
|
|
||||||
|
private IReadOnlyList<IBindable> settingsBacking;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of the all <see cref="IBindable"/> settings within this mod.
|
||||||
|
/// </summary>
|
||||||
|
internal IReadOnlyList<IBindable> Settings =>
|
||||||
|
settingsBacking ??= this.GetSettingsSourceProperties()
|
||||||
|
.Select(p => p.Item2.GetValue(this))
|
||||||
|
.Cast<IBindable>()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a copy of this <see cref="Mod"/> initialised to a default state.
|
/// Creates a copy of this <see cref="Mod"/> initialised to a default state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -191,15 +202,39 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
if (ReferenceEquals(this, other)) return true;
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
|
||||||
return GetType() == other.GetType() &&
|
return GetType() == other.GetType() &&
|
||||||
this.GetSettingsSourceProperties().All(pair =>
|
Settings.SequenceEqual(other.Settings, ModSettingsEqualityComparer.Default);
|
||||||
EqualityComparer<object>.Default.Equals(
|
}
|
||||||
ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(this)),
|
|
||||||
ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(other))));
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
var hashCode = new HashCode();
|
||||||
|
|
||||||
|
hashCode.Add(GetType());
|
||||||
|
|
||||||
|
foreach (var setting in Settings)
|
||||||
|
hashCode.Add(ModUtils.GetSettingUnderlyingValue(setting));
|
||||||
|
|
||||||
|
return hashCode.ToHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reset all custom settings for this mod back to their defaults.
|
/// Reset all custom settings for this mod back to their defaults.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void ResetSettingsToDefaults() => CopyFrom((Mod)Activator.CreateInstance(GetType()));
|
public virtual void ResetSettingsToDefaults() => CopyFrom((Mod)Activator.CreateInstance(GetType()));
|
||||||
|
|
||||||
|
private class ModSettingsEqualityComparer : IEqualityComparer<IBindable>
|
||||||
|
{
|
||||||
|
public static ModSettingsEqualityComparer Default { get; } = new ModSettingsEqualityComparer();
|
||||||
|
|
||||||
|
public bool Equals(IBindable x, IBindable y)
|
||||||
|
{
|
||||||
|
object xValue = x == null ? null : ModUtils.GetSettingUnderlyingValue(x);
|
||||||
|
object yValue = y == null ? null : ModUtils.GetSettingUnderlyingValue(y);
|
||||||
|
|
||||||
|
return EqualityComparer<object>.Default.Equals(xValue, yValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(IBindable obj) => ModUtils.GetSettingUnderlyingValue(obj).GetHashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ namespace osu.Game.Screens.Select
|
|||||||
public const float BORDER_THICKNESS = 2.5f;
|
public const float BORDER_THICKNESS = 2.5f;
|
||||||
private const float shear_width = 36.75f;
|
private const float shear_width = 36.75f;
|
||||||
|
|
||||||
|
private const float transition_duration = 250;
|
||||||
|
|
||||||
private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0);
|
private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -45,11 +47,6 @@ namespace osu.Game.Screens.Select
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapDifficultyCache difficultyCache { get; set; }
|
|
||||||
|
|
||||||
private IBindable<StarDifficulty?> beatmapDifficulty;
|
|
||||||
|
|
||||||
protected Container DisplayedContent { get; private set; }
|
protected Container DisplayedContent { get; private set; }
|
||||||
|
|
||||||
protected WedgeInfoText Info { get; private set; }
|
protected WedgeInfoText Info { get; private set; }
|
||||||
@ -76,24 +73,24 @@ namespace osu.Game.Screens.Select
|
|||||||
ruleset.BindValueChanged(_ => updateDisplay());
|
ruleset.BindValueChanged(_ => updateDisplay());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const double animation_duration = 800;
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
this.MoveToX(0, 800, Easing.OutQuint);
|
this.MoveToX(0, animation_duration, Easing.OutQuint);
|
||||||
this.RotateTo(0, 800, Easing.OutQuint);
|
this.RotateTo(0, animation_duration, Easing.OutQuint);
|
||||||
this.FadeIn(250);
|
this.FadeIn(transition_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
this.MoveToX(-100, 800, Easing.In);
|
this.MoveToX(-100, animation_duration, Easing.In);
|
||||||
this.RotateTo(10, 800, Easing.In);
|
this.RotateTo(10, animation_duration, Easing.In);
|
||||||
this.FadeOut(500, Easing.In);
|
this.FadeOut(transition_duration * 2, Easing.In);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WorkingBeatmap beatmap;
|
private WorkingBeatmap beatmap;
|
||||||
|
|
||||||
private CancellationTokenSource cancellationSource;
|
|
||||||
|
|
||||||
public WorkingBeatmap Beatmap
|
public WorkingBeatmap Beatmap
|
||||||
{
|
{
|
||||||
get => beatmap;
|
get => beatmap;
|
||||||
@ -102,12 +99,6 @@ namespace osu.Game.Screens.Select
|
|||||||
if (beatmap == value) return;
|
if (beatmap == value) return;
|
||||||
|
|
||||||
beatmap = value;
|
beatmap = value;
|
||||||
cancellationSource?.Cancel();
|
|
||||||
cancellationSource = new CancellationTokenSource();
|
|
||||||
|
|
||||||
beatmapDifficulty?.UnbindAll();
|
|
||||||
beatmapDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token);
|
|
||||||
beatmapDifficulty.BindValueChanged(_ => updateDisplay());
|
|
||||||
|
|
||||||
updateDisplay();
|
updateDisplay();
|
||||||
}
|
}
|
||||||
@ -127,7 +118,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible;
|
State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible;
|
||||||
|
|
||||||
DisplayedContent?.FadeOut(250);
|
DisplayedContent?.FadeOut(transition_duration);
|
||||||
DisplayedContent?.Expire();
|
DisplayedContent?.Expire();
|
||||||
DisplayedContent = null;
|
DisplayedContent = null;
|
||||||
}
|
}
|
||||||
@ -146,7 +137,7 @@ namespace osu.Game.Screens.Select
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new BeatmapInfoWedgeBackground(beatmap),
|
new BeatmapInfoWedgeBackground(beatmap),
|
||||||
Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value ?? new StarDifficulty()),
|
Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value),
|
||||||
}
|
}
|
||||||
}, loaded =>
|
}, loaded =>
|
||||||
{
|
{
|
||||||
@ -159,12 +150,6 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
cancellationSource?.Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class WedgeInfoText : Container
|
public class WedgeInfoText : Container
|
||||||
{
|
{
|
||||||
public OsuSpriteText VersionLabel { get; private set; }
|
public OsuSpriteText VersionLabel { get; private set; }
|
||||||
@ -173,6 +158,9 @@ namespace osu.Game.Screens.Select
|
|||||||
public BeatmapSetOnlineStatusPill StatusPill { get; private set; }
|
public BeatmapSetOnlineStatusPill StatusPill { get; private set; }
|
||||||
public FillFlowContainer MapperContainer { get; private set; }
|
public FillFlowContainer MapperContainer { get; private set; }
|
||||||
|
|
||||||
|
private Container difficultyColourBar;
|
||||||
|
private StarRatingDisplay starRatingDisplay;
|
||||||
|
|
||||||
private ILocalisedBindableString titleBinding;
|
private ILocalisedBindableString titleBinding;
|
||||||
private ILocalisedBindableString artistBinding;
|
private ILocalisedBindableString artistBinding;
|
||||||
private FillFlowContainer infoLabelContainer;
|
private FillFlowContainer infoLabelContainer;
|
||||||
@ -181,20 +169,21 @@ namespace osu.Game.Screens.Select
|
|||||||
private readonly WorkingBeatmap beatmap;
|
private readonly WorkingBeatmap beatmap;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
private readonly IReadOnlyList<Mod> mods;
|
private readonly IReadOnlyList<Mod> mods;
|
||||||
private readonly StarDifficulty starDifficulty;
|
|
||||||
|
|
||||||
private ModSettingChangeTracker settingChangeTracker;
|
private ModSettingChangeTracker settingChangeTracker;
|
||||||
|
|
||||||
public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList<Mod> mods, StarDifficulty difficulty)
|
public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList<Mod> mods)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
|
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
|
||||||
this.mods = mods;
|
this.mods = mods;
|
||||||
starDifficulty = difficulty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CancellationTokenSource cancellationSource;
|
||||||
|
private IBindable<StarDifficulty?> starDifficulty;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(LocalisationManager localisation)
|
private void load(OsuColour colours, LocalisationManager localisation, BeatmapDifficultyCache difficultyCache)
|
||||||
{
|
{
|
||||||
var beatmapInfo = beatmap.BeatmapInfo;
|
var beatmapInfo = beatmap.BeatmapInfo;
|
||||||
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||||
@ -204,12 +193,30 @@ namespace osu.Game.Screens.Select
|
|||||||
titleBinding = localisation.GetLocalisedString(new RomanisableString(metadata.TitleUnicode, metadata.Title));
|
titleBinding = localisation.GetLocalisedString(new RomanisableString(metadata.TitleUnicode, metadata.Title));
|
||||||
artistBinding = localisation.GetLocalisedString(new RomanisableString(metadata.ArtistUnicode, metadata.Artist));
|
artistBinding = localisation.GetLocalisedString(new RomanisableString(metadata.ArtistUnicode, metadata.Artist));
|
||||||
|
|
||||||
|
const float top_height = 0.7f;
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DifficultyColourBar(starDifficulty)
|
difficultyColourBar = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
Width = 20,
|
Width = 20f,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = top_height,
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
RelativePositionAxes = Axes.Both,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
X = top_height,
|
||||||
|
Width = 1 - top_height,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
@ -240,14 +247,16 @@ namespace osu.Game.Screens.Select
|
|||||||
Padding = new MarginPadding { Top = 14, Right = shear_width / 2 },
|
Padding = new MarginPadding { Top = 14, Right = shear_width / 2 },
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Shear = wedged_container_shear,
|
Shear = wedged_container_shear,
|
||||||
Children = new[]
|
Spacing = new Vector2(0f, 5f),
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
createStarRatingDisplay(starDifficulty).With(display =>
|
starRatingDisplay = new StarRatingDisplay(default, animated: true)
|
||||||
{
|
{
|
||||||
display.Anchor = Anchor.TopRight;
|
Anchor = Anchor.TopRight,
|
||||||
display.Origin = Anchor.TopRight;
|
Origin = Anchor.TopRight,
|
||||||
display.Shear = -wedged_container_shear;
|
Shear = -wedged_container_shear,
|
||||||
}),
|
Alpha = 0f,
|
||||||
|
},
|
||||||
StatusPill = new BeatmapSetOnlineStatusPill
|
StatusPill = new BeatmapSetOnlineStatusPill
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
@ -303,6 +312,18 @@ namespace osu.Game.Screens.Select
|
|||||||
titleBinding.BindValueChanged(_ => setMetadata(metadata.Source));
|
titleBinding.BindValueChanged(_ => setMetadata(metadata.Source));
|
||||||
artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true);
|
artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true);
|
||||||
|
|
||||||
|
starRatingDisplay.DisplayedStars.BindValueChanged(s =>
|
||||||
|
{
|
||||||
|
difficultyColourBar.Colour = colours.ForStarDifficulty(s.NewValue);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
starDifficulty = difficultyCache.GetBindableDifficulty(beatmapInfo, (cancellationSource = new CancellationTokenSource()).Token);
|
||||||
|
starDifficulty.BindValueChanged(s =>
|
||||||
|
{
|
||||||
|
starRatingDisplay.FadeIn(transition_duration);
|
||||||
|
starRatingDisplay.Current.Value = s.NewValue ?? default;
|
||||||
|
});
|
||||||
|
|
||||||
// no difficulty means it can't have a status to show
|
// no difficulty means it can't have a status to show
|
||||||
if (beatmapInfo.Version == null)
|
if (beatmapInfo.Version == null)
|
||||||
StatusPill.Hide();
|
StatusPill.Hide();
|
||||||
@ -310,13 +331,6 @@ namespace osu.Game.Screens.Select
|
|||||||
addInfoLabels();
|
addInfoLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Drawable createStarRatingDisplay(StarDifficulty difficulty) => difficulty.Stars > 0
|
|
||||||
? new StarRatingDisplay(difficulty)
|
|
||||||
{
|
|
||||||
Margin = new MarginPadding { Bottom = 5 }
|
|
||||||
}
|
|
||||||
: Empty();
|
|
||||||
|
|
||||||
private void setMetadata(string source)
|
private void setMetadata(string source)
|
||||||
{
|
{
|
||||||
ArtistLabel.Text = artistBinding.Value;
|
ArtistLabel.Text = artistBinding.Value;
|
||||||
@ -428,6 +442,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
settingChangeTracker?.Dispose();
|
settingChangeTracker?.Dispose();
|
||||||
|
cancellationSource?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InfoLabel : Container, IHasTooltip
|
public class InfoLabel : Container, IHasTooltip
|
||||||
@ -488,43 +503,6 @@ namespace osu.Game.Screens.Select
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DifficultyColourBar : Container
|
|
||||||
{
|
|
||||||
private readonly StarDifficulty difficulty;
|
|
||||||
|
|
||||||
public DifficultyColourBar(StarDifficulty difficulty)
|
|
||||||
{
|
|
||||||
this.difficulty = difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
const float full_opacity_ratio = 0.7f;
|
|
||||||
|
|
||||||
var difficultyColour = colours.ForStarDifficulty(difficulty.Stars);
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = difficultyColour,
|
|
||||||
Width = full_opacity_ratio,
|
|
||||||
},
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Colour = difficultyColour,
|
|
||||||
Alpha = 0.5f,
|
|
||||||
X = full_opacity_ratio,
|
|
||||||
Width = 1 - full_opacity_ratio,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user