diff --git a/PerformanceCalculatorGUI/Components/ExtendedProfileScore.cs b/PerformanceCalculatorGUI/Components/ExtendedProfileScore.cs index af8630e..60da192 100644 --- a/PerformanceCalculatorGUI/Components/ExtendedProfileScore.cs +++ b/PerformanceCalculatorGUI/Components/ExtendedProfileScore.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -15,6 +17,8 @@ namespace PerformanceCalculatorGUI.Components { public double LivePP { get; } + public Bindable PositionChange { get; } = new(); + public ExtendedScore(APIScore score, double livePP) { LivePP = livePP; @@ -39,12 +43,34 @@ namespace PerformanceCalculatorGUI.Components { protected readonly ExtendedScore ExtendedScore; + private OsuSpriteText positionChangeText; + public ExtendedProfileScore(ExtendedScore score) : base(score) { ExtendedScore = score; } + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new Container + { + RelativeSizeAxes = Axes.Y, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 25, + Child = positionChangeText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = ExtendedScore.PositionChange.Value.ToString() + } + }); + + ExtendedScore.PositionChange.BindValueChanged(v => { positionChangeText.Text = $"{v.NewValue:+0;-0;-}"; }); + } + protected override Drawable CreateRightContent() => new FillFlowContainer { AutoSizeAxes = Axes.Both, diff --git a/PerformanceCalculatorGUI/Screens/ProfileScreen.cs b/PerformanceCalculatorGUI/Screens/ProfileScreen.cs index 5d76267..adf1b35 100644 --- a/PerformanceCalculatorGUI/Screens/ProfileScreen.cs +++ b/PerformanceCalculatorGUI/Screens/ProfileScreen.cs @@ -185,55 +185,61 @@ namespace PerformanceCalculatorGUI.Screens foreach (var score in apiScores) { - await Task.Run(() => + var working = ProcessorWorkingBeatmap.FromFileOrId(score.Beatmap?.OnlineID.ToString()); + + Schedule(() => loadingLayer.Text.Value = $"Calculating {working.Metadata}"); + + var modsAcronyms = score.Mods.Select(x => x.ToString()).ToArray(); + Mod[] mods = rulesetInstance.CreateAllMods().Where(m => modsAcronyms.Contains(m.Acronym)).ToArray(); + + var scoreInfo = new ScoreInfo(working.BeatmapInfo, ruleset.Value) { - var working = ProcessorWorkingBeatmap.FromFileOrId(score.Beatmap?.OnlineID.ToString()); + TotalScore = score.TotalScore, + MaxCombo = score.MaxCombo, + Mods = mods, + Statistics = new Dictionary() + }; - Schedule(() => loadingLayer.Text.Value = $"Calculating {working.Metadata}"); + scoreInfo.SetCount300(score.Statistics["count_300"]); + scoreInfo.SetCountGeki(score.Statistics["count_geki"]); + scoreInfo.SetCount100(score.Statistics["count_100"]); + scoreInfo.SetCountKatu(score.Statistics["count_katu"]); + scoreInfo.SetCount50(score.Statistics["count_50"]); + scoreInfo.SetCountMiss(score.Statistics["count_miss"]); - var modsAcronyms = score.Mods.Select(x => x.ToString()).ToArray(); - Mod[] mods = rulesetInstance.CreateAllMods().Where(m => modsAcronyms.Contains(m.Acronym)).ToArray(); + var parsedScore = new ProcessorScoreDecoder(working).Parse(scoreInfo); - var scoreInfo = new ScoreInfo(working.BeatmapInfo, ruleset.Value) - { - TotalScore = score.TotalScore, - MaxCombo = score.MaxCombo, - Mods = mods, - Statistics = new Dictionary() - }; + var difficultyCalculator = rulesetInstance.CreateDifficultyCalculator(working); + var difficultyAttributes = difficultyCalculator.Calculate(scoreInfo.Mods); + var performanceCalculator = rulesetInstance.CreatePerformanceCalculator(difficultyAttributes, parsedScore.ScoreInfo); - scoreInfo.SetCount300(score.Statistics["count_300"]); - scoreInfo.SetCountGeki(score.Statistics["count_geki"]); - scoreInfo.SetCount100(score.Statistics["count_100"]); - scoreInfo.SetCountKatu(score.Statistics["count_katu"]); - scoreInfo.SetCount50(score.Statistics["count_50"]); - scoreInfo.SetCountMiss(score.Statistics["count_miss"]); + var livePp = score.PP ?? 0.0; + score.PP = performanceCalculator?.Calculate().Total ?? 0.0; - var parsedScore = new ProcessorScoreDecoder(working).Parse(scoreInfo); + var extendedScore = new ExtendedScore(score, livePp); + plays.Add(extendedScore); - var difficultyCalculator = rulesetInstance.CreateDifficultyCalculator(working); - var difficultyAttributes = difficultyCalculator.Calculate(scoreInfo.Mods); - var performanceCalculator = rulesetInstance.CreatePerformanceCalculator(difficultyAttributes, parsedScore.ScoreInfo); - - var livePp = score.PP ?? 0.0; - score.PP = performanceCalculator?.Calculate().Total ?? 0.0; - - var extendedScore = new ExtendedScore(score, livePp); - plays.Add(extendedScore); - - Schedule(() => scores.Add(new ExtendedProfileScore(extendedScore))); - }); + Schedule(() => scores.Add(new ExtendedProfileScore(extendedScore))); } - var localOrdered = plays.Select(x => x.PP).OrderByDescending(x => x).ToList(); - var liveOrdered = plays.Select(x => x.LivePP).OrderByDescending(x => x).ToList(); + var localOrdered = plays.OrderByDescending(x => x.PP).ToList(); + var liveOrdered = plays.OrderByDescending(x => x.LivePP).ToList(); + + Schedule(() => + { + foreach (var play in plays) + { + play.PositionChange.Value = liveOrdered.IndexOf(play) - localOrdered.IndexOf(play); + scores.SetLayoutPosition(scores[liveOrdered.IndexOf(play)], localOrdered.IndexOf(play)); + } + }); int index = 0; - decimal totalLocalPP = (decimal)localOrdered.Sum(play => Math.Pow(0.95, index++) * play); + decimal totalLocalPP = (decimal)localOrdered.Select(x=> x.PP).Sum(play => Math.Pow(0.95, index++) * play); decimal totalLivePP = player.Statistics.PP ?? (decimal)0.0; index = 0; - decimal nonBonusLivePP = (decimal)liveOrdered.Sum(play => Math.Pow(0.95, index++) * play); + decimal nonBonusLivePP = (decimal)liveOrdered.Select(x => x.LivePP).Sum(play => Math.Pow(0.95, index++) * play); //todo: implement properly. this is pretty damn wrong. var playcountBonusPP = (totalLivePP - nonBonusLivePP);