1
0
Fork 0
mirror of https://github.com/ppy/osu-tools.git synced 2025-06-09 09:35:15 +09:00

Add performance attributes tooltip to profile scores

This commit is contained in:
StanR 2022-03-29 04:50:30 +03:00
parent 8cd8418125
commit d98d6b8823
5 changed files with 127 additions and 13 deletions

View file

@ -0,0 +1,35 @@
// 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.Collections.Generic;
using System.Linq;
using Humanizer;
using Newtonsoft.Json;
using osu.Game.Rulesets.Difficulty;
namespace PerformanceCalculatorGUI
{
internal static class AttributeConversion
{
public static Dictionary<string, object> ToDictionary(DifficultyAttributes attributes)
{
var attributeValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(attributes)) ?? new Dictionary<string, object>();
return attributeValues.Select(x => new KeyValuePair<string, object>(x.Key.Humanize().ToLowerInvariant(), x.Value)).ToDictionary(x => x.Key, y => y.Value);
}
public static Dictionary<string, object> ToDictionary(PerformanceAttributes attributes)
{
var attributeValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(attributes)) ?? new Dictionary<string, object>();
return attributeValues.Select(x => new KeyValuePair<string, object>(x.Key.Humanize().ToLowerInvariant(), x.Value)).ToDictionary(x => x.Key, y => y.Value);
}
public static string ToReadableString(PerformanceAttributes attributes)
{
var dictionary = ToDictionary(attributes);
return string.Join("\n", dictionary.Select(x=> $"{x.Key}: {x.Value:N2}"));
}
}
}

View file

@ -0,0 +1,71 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osuTK;
namespace PerformanceCalculatorGUI.Components
{
internal class ExtendedOsuSpriteText : OsuSpriteText, IHasCustomTooltip<string>
{
public override bool HandlePositionalInput => true;
public string TooltipContent { get; set; }
public ITooltip<string> GetCustomTooltip() => new MultilineTooltip();
}
public class MultilineTooltip : VisibilityContainer, ITooltip<string>
{
private readonly FillFlowContainer textContainer;
private string currentData;
public MultilineTooltip()
{
AutoSizeAxes = Axes.Both;
Masking = true;
CornerRadius = 5;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.85f,
Colour = OsuColour.Gray(0.1f)
},
textContainer = new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Padding = new MarginPadding(10),
},
};
}
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
public void SetContent(string data)
{
if (currentData == data)
return;
textContainer.Clear();
currentData = data;
var split = data.Split('\n');
foreach (var line in split)
textContainer.Add(new OsuSpriteText { Text = line });
}
public void Move(Vector2 pos) => Position = pos;
}
}

View file

@ -3,22 +3,26 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Sections;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.UI;
using osu.Game.Utils;
using osuTK;
@ -31,8 +35,11 @@ namespace PerformanceCalculatorGUI.Components
public Bindable<int> PositionChange { get; } = new();
public ExtendedScore(APIScore score, double livePP)
public PerformanceAttributes PerformanceAttributes { get; }
public ExtendedScore(APIScore score, double livePP, PerformanceAttributes attributes)
{
PerformanceAttributes = attributes;
LivePP = livePP;
TotalScore = score.TotalScore;
@ -56,6 +63,7 @@ namespace PerformanceCalculatorGUI.Components
private const int height = 40;
private const int performance_width = 100;
private const int rank_difference_width = 35;
private const int small_text_font_size = 11;
private const float performance_background_shear = 0.45f;
@ -205,7 +213,7 @@ namespace PerformanceCalculatorGUI.Components
new OsuSpriteText
{
Text = $"{Score.MaxCombo}x {{ {Score.Statistics["count_300"]} / {Score.Statistics["count_100"]} / {Score.Statistics["count_50"]} / {Score.Statistics["count_miss"]} }}",
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Regular),
Font = OsuFont.GetFont(size: small_text_font_size, weight: FontWeight.Regular),
Colour = colourProvider.Light2,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
@ -227,12 +235,12 @@ namespace PerformanceCalculatorGUI.Components
Child = new OsuSpriteText
{
Font = OsuFont.GetFont(weight: FontWeight.Bold),
Text = $"{Score.LivePP:0}pp",
Text = $"{Score.LivePP:0}pp"
},
},
new OsuSpriteText
{
Font = OsuFont.GetFont(size: 10),
Font = OsuFont.GetFont(size: small_text_font_size),
Text = "live"
}
}
@ -308,17 +316,18 @@ namespace PerformanceCalculatorGUI.Components
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new OsuSpriteText
new ExtendedOsuSpriteText
{
Font = OsuFont.GetFont(weight: FontWeight.Bold),
Text = $"{Score.PP:0}pp",
Colour = colourProvider.Highlight1,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
Origin = Anchor.TopCentre,
TooltipContent = $"{AttributeConversion.ToReadableString(Score.PerformanceAttributes)}"
},
new OsuSpriteText
{
Font = OsuFont.GetFont(size: 10),
Font = OsuFont.GetFont(size: small_text_font_size),
Text = $"{Score.PP - Score.LivePP:+0.0;-0.0;-}",
Colour = colourProvider.Light1,
Anchor = Anchor.TopCentre,

View file

@ -215,9 +215,10 @@ namespace PerformanceCalculatorGUI.Screens
var performanceCalculator = rulesetInstance.CreatePerformanceCalculator();
var livePp = score.PP ?? 0.0;
score.PP = performanceCalculator?.Calculate(parsedScore.ScoreInfo, difficultyAttributes).Total ?? 0.0;
var perfAttributes = performanceCalculator?.Calculate(parsedScore.ScoreInfo, difficultyAttributes);
score.PP = perfAttributes?.Total ?? 0.0;
var extendedScore = new ExtendedScore(score, livePp);
var extendedScore = new ExtendedScore(score, livePp, perfAttributes);
plays.Add(extendedScore);
Schedule(() => scores.Add(new ExtendedProfileScore(extendedScore)));

View file

@ -594,8 +594,7 @@ namespace PerformanceCalculatorGUI.Screens
populateScoreParams();
var diffAttributeValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(difficultyAttributes)) ?? new Dictionary<string, object>();
difficultyAttributesContainer.Children = diffAttributeValues.Select(x =>
difficultyAttributesContainer.Children = AttributeConversion.ToDictionary(difficultyAttributes).Select(x =>
new LabelledTextBox
{
ReadOnly = true,
@ -651,8 +650,7 @@ namespace PerformanceCalculatorGUI.Screens
Ruleset = ruleset.Value
}, difficultyAttributes);
var perfAttributeValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(ppAttributes)) ?? new Dictionary<string, object>();
performanceAttributesContainer.Children = perfAttributeValues.Select(x =>
performanceAttributesContainer.Children = AttributeConversion.ToDictionary(ppAttributes).Select(x =>
new LabelledTextBox
{
ReadOnly = true,