Merge pull request #10106 from smoogipoo/score-recalc

This commit is contained in:
Dean Herbert 2020-09-10 19:05:42 +09:00 committed by GitHub
commit 23b51e8f7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 207 additions and 26 deletions

View File

@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Catch.Difficulty
public class CatchDifficultyAttributes : DifficultyAttributes public class CatchDifficultyAttributes : DifficultyAttributes
{ {
public double ApproachRate; public double ApproachRate;
public int MaxCombo;
} }
} }

View File

@ -11,6 +11,7 @@ using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing; using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mania.Difficulty.Skills; using osu.Game.Rulesets.Mania.Difficulty.Skills;
using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -43,6 +44,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
Mods = mods, Mods = mods,
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
GreatHitWindow = (int)(hitWindows.WindowFor(HitResult.Great)) / clockRate, GreatHitWindow = (int)(hitWindows.WindowFor(HitResult.Great)) / clockRate,
MaxCombo = beatmap.HitObjects.Sum(h => h is HoldNote ? 2 : 1),
Skills = skills Skills = skills
}; };
} }

View File

@ -11,6 +11,5 @@ namespace osu.Game.Rulesets.Osu.Difficulty
public double SpeedStrain; public double SpeedStrain;
public double ApproachRate; public double ApproachRate;
public double OverallDifficulty; public double OverallDifficulty;
public int MaxCombo;
} }
} }

View File

@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
public class TaikoDifficultyAttributes : DifficultyAttributes public class TaikoDifficultyAttributes : DifficultyAttributes
{ {
public double GreatHitWindow; public double GreatHitWindow;
public int MaxCombo;
} }
} }

View File

@ -207,11 +207,11 @@ namespace osu.Game.Beatmaps
var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(beatmapInfo)); var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(beatmapInfo));
var attributes = calculator.Calculate(key.Mods); var attributes = calculator.Calculate(key.Mods);
return difficultyCache[key] = new StarDifficulty(attributes.StarRating); return difficultyCache[key] = new StarDifficulty(attributes.StarRating, attributes.MaxCombo);
} }
catch catch
{ {
return difficultyCache[key] = new StarDifficulty(0); return difficultyCache[key] = new StarDifficulty();
} }
} }
@ -233,7 +233,7 @@ namespace osu.Game.Beatmaps
if (beatmapInfo.ID == 0 || rulesetInfo.ID == null) if (beatmapInfo.ID == 0 || rulesetInfo.ID == null)
{ {
// If not, fall back to the existing star difficulty (e.g. from an online source). // If not, fall back to the existing star difficulty (e.g. from an online source).
existingDifficulty = new StarDifficulty(beatmapInfo.StarDifficulty); existingDifficulty = new StarDifficulty(beatmapInfo.StarDifficulty, beatmapInfo.MaxCombo ?? 0);
key = default; key = default;
return true; return true;
@ -298,10 +298,12 @@ namespace osu.Game.Beatmaps
public readonly struct StarDifficulty public readonly struct StarDifficulty
{ {
public readonly double Stars; public readonly double Stars;
public readonly int MaxCombo;
public StarDifficulty(double stars) public StarDifficulty(double stars, int maxCombo)
{ {
Stars = stars; Stars = stars;
MaxCombo = maxCombo;
// Todo: Add more members (BeatmapInfo.DifficultyRating? Attributes? Etc...) // Todo: Add more members (BeatmapInfo.DifficultyRating? Attributes? Etc...)
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -55,6 +56,12 @@ namespace osu.Game.Graphics.Sprites
set => spriteText.UseFullGlyphHeight = blurredText.UseFullGlyphHeight = value; set => spriteText.UseFullGlyphHeight = blurredText.UseFullGlyphHeight = value;
} }
public Bindable<string> Current
{
get => spriteText.Current;
set => spriteText.Current = value;
}
public GlowingSpriteText() public GlowingSpriteText()
{ {
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;

View File

@ -72,7 +72,7 @@ namespace osu.Game.Online.Leaderboards
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(IAPIProvider api, OsuColour colour) private void load(IAPIProvider api, OsuColour colour, ScoreManager scoreManager)
{ {
var user = score.User; var user = score.User;
@ -194,7 +194,7 @@ namespace osu.Game.Online.Leaderboards
{ {
TextColour = Color4.White, TextColour = Color4.White,
GlowColour = Color4Extensions.FromHex(@"83ccfa"), GlowColour = Color4Extensions.FromHex(@"83ccfa"),
Text = score.TotalScore.ToString(@"N0"), Current = scoreManager.GetBindableTotalScoreString(score),
Font = OsuFont.Numeric.With(size: 23), Font = OsuFont.Numeric.With(size: 23),
}, },
RankContainer = new Container RankContainer = new Container

View File

@ -58,6 +58,8 @@ namespace osu.Game
protected ScoreManager ScoreManager; protected ScoreManager ScoreManager;
protected BeatmapDifficultyManager DifficultyManager;
protected SkinManager SkinManager; protected SkinManager SkinManager;
protected RulesetStore RulesetStore; protected RulesetStore RulesetStore;
@ -197,7 +199,7 @@ namespace osu.Game
dependencies.Cache(FileStore = new FileStore(contextFactory, Storage)); dependencies.Cache(FileStore = new FileStore(contextFactory, Storage));
// ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup() // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup()
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host)); dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host, () => DifficultyManager, LocalConfig));
dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap, true)); dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap, true));
// this should likely be moved to ArchiveModelManager when another case appers where it is necessary // this should likely be moved to ArchiveModelManager when another case appers where it is necessary
@ -221,9 +223,8 @@ namespace osu.Game
ScoreManager.Undelete(getBeatmapScores(item), true); ScoreManager.Undelete(getBeatmapScores(item), true);
}); });
var difficultyManager = new BeatmapDifficultyManager(); dependencies.Cache(DifficultyManager = new BeatmapDifficultyManager());
dependencies.Cache(difficultyManager); AddInternal(DifficultyManager);
AddInternal(difficultyManager);
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory)); dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));

View File

@ -25,6 +25,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private const float row_height = 22; private const float row_height = 22;
private const int text_size = 12; private const int text_size = 12;
[Resolved]
private ScoreManager scoreManager { get; set; }
private readonly FillFlowContainer backgroundFlow; private readonly FillFlowContainer backgroundFlow;
private Color4 highAccuracyColour; private Color4 highAccuracyColour;
@ -121,7 +124,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
new OsuSpriteText new OsuSpriteText
{ {
Margin = new MarginPadding { Right = horizontal_inset }, Margin = new MarginPadding { Right = horizontal_inset },
Text = $@"{score.TotalScore:N0}", Current = scoreManager.GetBindableTotalScoreString(score),
Font = OsuFont.GetFont(size: text_size, weight: index == 0 ? FontWeight.Bold : FontWeight.Medium) Font = OsuFont.GetFont(size: text_size, weight: index == 0 ? FontWeight.Bold : FontWeight.Medium)
}, },
new OsuSpriteText new OsuSpriteText

View File

@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -38,6 +39,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly FillFlowContainer<InfoColumn> statisticsColumns; private readonly FillFlowContainer<InfoColumn> statisticsColumns;
private readonly ModsInfoColumn modsColumn; private readonly ModsInfoColumn modsColumn;
[Resolved]
private ScoreManager scoreManager { get; set; }
public TopScoreStatisticsSection() public TopScoreStatisticsSection()
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
@ -87,6 +91,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
}; };
} }
[BackgroundDependencyLoader]
private void load()
{
if (score != null)
totalScoreColumn.Current = scoreManager.GetBindableTotalScoreString(score);
}
private ScoreInfo score;
/// <summary> /// <summary>
/// Sets the score to be displayed. /// Sets the score to be displayed.
/// </summary> /// </summary>
@ -94,7 +107,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
set set
{ {
totalScoreColumn.Text = $@"{value.TotalScore:N0}"; if (score == value)
return;
score = value;
accuracyColumn.Text = value.DisplayAccuracy; accuracyColumn.Text = value.DisplayAccuracy;
maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; maxComboColumn.Text = $@"{value.MaxCombo:N0}x";
ppColumn.Alpha = value.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0; ppColumn.Alpha = value.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0;
@ -102,6 +119,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value));
modsColumn.Mods = value.Mods; modsColumn.Mods = value.Mods;
if (scoreManager != null)
totalScoreColumn.Current = scoreManager.GetBindableTotalScoreString(value);
} }
} }
@ -190,6 +210,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
set => text.Text = value; set => text.Text = value;
} }
public Bindable<string> Current
{
get => text.Current;
set => text.Current = value;
}
} }
private class ModsInfoColumn : InfoColumn private class ModsInfoColumn : InfoColumn

View File

@ -12,6 +12,7 @@ namespace osu.Game.Rulesets.Difficulty
public Skill[] Skills; public Skill[] Skills;
public double StarRating; public double StarRating;
public int MaxCombo;
public DifficultyAttributes() public DifficultyAttributes()
{ {

View File

@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Scoring
private readonly double accuracyPortion; private readonly double accuracyPortion;
private readonly double comboPortion; private readonly double comboPortion;
private double maxHighestCombo; private int maxHighestCombo;
private double maxBaseScore; private double maxBaseScore;
private double rollingMaxBaseScore; private double rollingMaxBaseScore;
private double baseScore; private double baseScore;
@ -202,20 +202,31 @@ namespace osu.Game.Rulesets.Scoring
TotalScore.Value = getScore(Mode.Value); TotalScore.Value = getScore(Mode.Value);
} }
private double getScore(ScoringMode mode) private double getScore(ScoringMode mode) => GetScore(mode, maxHighestCombo, baseScore / maxBaseScore, (double)HighestCombo.Value / maxHighestCombo, bonusScore);
/// <summary>
/// Computes the total score.
/// </summary>
/// <param name="mode">The <see cref="ScoringMode"/> to compute the total score in.</param>
/// <param name="maxCombo">The maximum combo achievable in the beatmap.</param>
/// <param name="accuracyRatio">The accuracy percentage achieved by the player.</param>
/// <param name="comboRatio">The proportion of <paramref name="maxCombo"/> achieved by the player.</param>
/// <param name="bonusScore">Any bonus score to be added.</param>
/// <returns>The total score.</returns>
public double GetScore(ScoringMode mode, int maxCombo, double accuracyRatio, double comboRatio, double bonusScore)
{ {
switch (mode) switch (mode)
{ {
default: default:
case ScoringMode.Standardised: case ScoringMode.Standardised:
double accuracyScore = accuracyPortion * baseScore / maxBaseScore; double accuracyScore = accuracyPortion * accuracyRatio;
double comboScore = comboPortion * HighestCombo.Value / maxHighestCombo; double comboScore = comboPortion * comboRatio;
return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier; return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier;
case ScoringMode.Classic: case ScoringMode.Classic:
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)
return bonusScore + baseScore * (1 + Math.Max(0, HighestCombo.Value - 1) * scoreMultiplier / 25); return bonusScore + (accuracyRatio * maxCombo * 300) * (1 + Math.Max(0, (comboRatio * maxCombo) - 1) * scoreMultiplier / 25);
} }
} }

View File

@ -6,15 +6,20 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using osu.Framework.Bindables;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.IO.Archives; using osu.Game.IO.Archives;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring.Legacy; using osu.Game.Scoring.Legacy;
namespace osu.Game.Scoring namespace osu.Game.Scoring
@ -30,11 +35,20 @@ namespace osu.Game.Scoring
private readonly RulesetStore rulesets; private readonly RulesetStore rulesets;
private readonly Func<BeatmapManager> beatmaps; private readonly Func<BeatmapManager> beatmaps;
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, IAPIProvider api, IDatabaseContextFactory contextFactory, IIpcHost importHost = null) [CanBeNull]
private readonly Func<BeatmapDifficultyManager> difficulties;
[CanBeNull]
private readonly OsuConfigManager configManager;
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, IAPIProvider api, IDatabaseContextFactory contextFactory, IIpcHost importHost = null,
Func<BeatmapDifficultyManager> difficulties = null, OsuConfigManager configManager = null)
: base(storage, contextFactory, api, new ScoreStore(contextFactory, storage), importHost) : base(storage, contextFactory, api, new ScoreStore(contextFactory, storage), importHost)
{ {
this.rulesets = rulesets; this.rulesets = rulesets;
this.beatmaps = beatmaps; this.beatmaps = beatmaps;
this.difficulties = difficulties;
this.configManager = configManager;
} }
protected override ScoreInfo CreateModel(ArchiveReader archive) protected override ScoreInfo CreateModel(ArchiveReader archive)
@ -72,5 +86,118 @@ namespace osu.Game.Scoring
protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items) protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items)
=> base.CheckLocalAvailability(model, items) => base.CheckLocalAvailability(model, items)
|| (model.OnlineScoreID != null && items.Any(i => i.OnlineScoreID == model.OnlineScoreID)); || (model.OnlineScoreID != null && items.Any(i => i.OnlineScoreID == model.OnlineScoreID));
/// <summary>
/// Retrieves a bindable that represents the total score of a <see cref="ScoreInfo"/>.
/// </summary>
/// <remarks>
/// Responds to changes in the currently-selected <see cref="ScoringMode"/>.
/// </remarks>
/// <param name="score">The <see cref="ScoreInfo"/> to retrieve the bindable for.</param>
/// <returns>The bindable containing the total score.</returns>
public Bindable<long> GetBindableTotalScore(ScoreInfo score)
{
var bindable = new TotalScoreBindable(score, difficulties);
configManager?.BindWith(OsuSetting.ScoreDisplayMode, bindable.ScoringMode);
return bindable;
}
/// <summary>
/// Retrieves a bindable that represents the formatted total score string of a <see cref="ScoreInfo"/>.
/// </summary>
/// <remarks>
/// Responds to changes in the currently-selected <see cref="ScoringMode"/>.
/// </remarks>
/// <param name="score">The <see cref="ScoreInfo"/> to retrieve the bindable for.</param>
/// <returns>The bindable containing the formatted total score string.</returns>
public Bindable<string> GetBindableTotalScoreString(ScoreInfo score) => new TotalScoreStringBindable(GetBindableTotalScore(score));
/// <summary>
/// Provides the total score of a <see cref="ScoreInfo"/>. Responds to changes in the currently-selected <see cref="ScoringMode"/>.
/// </summary>
private class TotalScoreBindable : Bindable<long>
{
public readonly Bindable<ScoringMode> ScoringMode = new Bindable<ScoringMode>();
private readonly ScoreInfo score;
private readonly Func<BeatmapDifficultyManager> difficulties;
/// <summary>
/// Creates a new <see cref="TotalScoreBindable"/>.
/// </summary>
/// <param name="score">The <see cref="ScoreInfo"/> to provide the total score of.</param>
/// <param name="difficulties">A function to retrieve the <see cref="BeatmapDifficultyManager"/>.</param>
public TotalScoreBindable(ScoreInfo score, Func<BeatmapDifficultyManager> difficulties)
{
this.score = score;
this.difficulties = difficulties;
ScoringMode.BindValueChanged(onScoringModeChanged, true);
}
private IBindable<StarDifficulty> difficultyBindable;
private CancellationTokenSource difficultyCancellationSource;
private void onScoringModeChanged(ValueChangedEvent<ScoringMode> mode)
{
difficultyCancellationSource?.Cancel();
difficultyCancellationSource = null;
if (score.Beatmap == null)
{
Value = score.TotalScore;
return;
}
int? beatmapMaxCombo = score.Beatmap.MaxCombo;
if (beatmapMaxCombo == null)
{
if (score.Beatmap.ID == 0 || difficulties == null)
{
// We don't have enough information (max combo) to compute the score, so let's use the provided score.
Value = score.TotalScore;
return;
}
// We can compute the max combo locally after the async beatmap difficulty computation.
difficultyBindable = difficulties().GetBindableDifficulty(score.Beatmap, score.Ruleset, score.Mods, (difficultyCancellationSource = new CancellationTokenSource()).Token);
difficultyBindable.BindValueChanged(d => updateScore(d.NewValue.MaxCombo), true);
}
else
updateScore(beatmapMaxCombo.Value);
}
private void updateScore(int beatmapMaxCombo)
{
if (beatmapMaxCombo == 0)
{
Value = 0;
return;
}
var ruleset = score.Ruleset.CreateInstance();
var scoreProcessor = ruleset.CreateScoreProcessor();
scoreProcessor.Mods.Value = score.Mods;
Value = (long)Math.Round(scoreProcessor.GetScore(ScoringMode.Value, beatmapMaxCombo, score.Accuracy, (double)score.MaxCombo / beatmapMaxCombo, 0));
}
}
/// <summary>
/// Provides the total score of a <see cref="ScoreInfo"/> as a formatted string. Responds to changes in the currently-selected <see cref="ScoringMode"/>.
/// </summary>
private class TotalScoreStringBindable : Bindable<string>
{
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable (need to hold a reference)
private readonly IBindable<long> totalScore;
public TotalScoreStringBindable(IBindable<long> totalScore)
{
this.totalScore = totalScore;
this.totalScore.BindValueChanged(v => Value = v.NewValue.ToString("N0"), true);
}
}
} }
} }

View File

@ -30,6 +30,9 @@ namespace osu.Game.Screens.Ranking.Contracted
{ {
private readonly ScoreInfo score; private readonly ScoreInfo score;
[Resolved]
private ScoreManager scoreManager { get; set; }
/// <summary> /// <summary>
/// Creates a new <see cref="ContractedPanelMiddleContent"/>. /// Creates a new <see cref="ContractedPanelMiddleContent"/>.
/// </summary> /// </summary>
@ -160,7 +163,7 @@ namespace osu.Game.Screens.Ranking.Contracted
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Text = score.TotalScore.ToString("N0"), Current = scoreManager.GetBindableTotalScoreString(score),
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, fixedWidth: true), Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, fixedWidth: true),
Spacing = new Vector2(-1, 0) Spacing = new Vector2(-1, 0)
}, },

View File

@ -25,15 +25,16 @@ namespace osu.Game.Screens.Ranking.Expanded
/// </summary> /// </summary>
public class ExpandedPanelMiddleContent : CompositeDrawable public class ExpandedPanelMiddleContent : CompositeDrawable
{ {
private readonly ScoreInfo score; private const float padding = 10;
private readonly ScoreInfo score;
private readonly List<StatisticDisplay> statisticDisplays = new List<StatisticDisplay>(); private readonly List<StatisticDisplay> statisticDisplays = new List<StatisticDisplay>();
private FillFlowContainer starAndModDisplay; private FillFlowContainer starAndModDisplay;
private RollingCounter<long> scoreCounter; private RollingCounter<long> scoreCounter;
private const float padding = 10; [Resolved]
private ScoreManager scoreManager { get; set; }
/// <summary> /// <summary>
/// Creates a new <see cref="ExpandedPanelMiddleContent"/>. /// Creates a new <see cref="ExpandedPanelMiddleContent"/>.
@ -238,7 +239,7 @@ namespace osu.Game.Screens.Ranking.Expanded
using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DELAY, true)) using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DELAY, true))
{ {
scoreCounter.FadeIn(); scoreCounter.FadeIn();
scoreCounter.Current.Value = score.TotalScore; scoreCounter.Current = scoreManager.GetBindableTotalScore(score);
double delay = 0; double delay = 0;