mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 08:43:01 +08:00
Merge pull request #27053 from frenzibyte/unranked-pp-placeholder
Add support for displaying "unranked PP" placeholder
This commit is contained in:
commit
f7a223f328
@ -154,6 +154,19 @@ namespace osu.Game.Tests.Visual.Online
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUnrankedPP()
|
||||
{
|
||||
AddStep("Load scores with unranked PP", () =>
|
||||
{
|
||||
var allScores = createScores();
|
||||
allScores.Scores[0].Ranked = false;
|
||||
allScores.UserScore = createUserBest();
|
||||
allScores.UserScore.Score.Ranked = false;
|
||||
scoresContainer.Scores = allScores;
|
||||
});
|
||||
}
|
||||
|
||||
private ulong onlineID = 1;
|
||||
|
||||
private APIScoresCollection createScores()
|
||||
@ -184,6 +197,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 1234567890,
|
||||
Accuracy = 1,
|
||||
Ranked = true,
|
||||
},
|
||||
new SoloScoreInfo
|
||||
{
|
||||
@ -206,6 +220,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 1234789,
|
||||
Accuracy = 0.9997,
|
||||
Ranked = true,
|
||||
},
|
||||
new SoloScoreInfo
|
||||
{
|
||||
@ -227,6 +242,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 12345678,
|
||||
Accuracy = 0.9854,
|
||||
Ranked = true,
|
||||
},
|
||||
new SoloScoreInfo
|
||||
{
|
||||
@ -247,6 +263,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 1234567,
|
||||
Accuracy = 0.8765,
|
||||
Ranked = true,
|
||||
},
|
||||
new SoloScoreInfo
|
||||
{
|
||||
@ -263,6 +280,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 123456,
|
||||
Accuracy = 0.6543,
|
||||
Ranked = true,
|
||||
},
|
||||
}
|
||||
};
|
||||
@ -309,6 +327,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
MaxCombo = 1234,
|
||||
TotalScore = 123456,
|
||||
Accuracy = 0.6543,
|
||||
Ranked = true,
|
||||
},
|
||||
Position = 1337,
|
||||
};
|
||||
|
@ -40,7 +40,8 @@ namespace osu.Game.Tests.Visual.Online
|
||||
new APIMod { Acronym = new OsuModHardRock().Acronym },
|
||||
new APIMod { Acronym = new OsuModDoubleTime().Acronym },
|
||||
},
|
||||
Accuracy = 0.9813
|
||||
Accuracy = 0.9813,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var secondScore = new SoloScoreInfo
|
||||
@ -62,7 +63,8 @@ namespace osu.Game.Tests.Visual.Online
|
||||
new APIMod { Acronym = new OsuModHardRock().Acronym },
|
||||
new APIMod { Acronym = new OsuModDoubleTime().Acronym },
|
||||
},
|
||||
Accuracy = 0.998546
|
||||
Accuracy = 0.998546,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var thirdScore = new SoloScoreInfo
|
||||
@ -79,7 +81,8 @@ namespace osu.Game.Tests.Visual.Online
|
||||
DifficultyName = "Insane"
|
||||
},
|
||||
EndedAt = DateTimeOffset.Now,
|
||||
Accuracy = 0.9726
|
||||
Accuracy = 0.9726,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var noPPScore = new SoloScoreInfo
|
||||
@ -95,7 +98,26 @@ namespace osu.Game.Tests.Visual.Online
|
||||
DifficultyName = "[4K] Cataclysmic Hypernova"
|
||||
},
|
||||
EndedAt = DateTimeOffset.Now,
|
||||
Accuracy = 0.55879
|
||||
Accuracy = 0.55879,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var lovedScore = new SoloScoreInfo
|
||||
{
|
||||
Rank = ScoreRank.B,
|
||||
Beatmap = new APIBeatmap
|
||||
{
|
||||
BeatmapSet = new APIBeatmapSet
|
||||
{
|
||||
Title = "C18H27NO3(extend)",
|
||||
Artist = "Team Grimoire",
|
||||
},
|
||||
DifficultyName = "[4K] Cataclysmic Hypernova",
|
||||
Status = BeatmapOnlineStatus.Loved,
|
||||
},
|
||||
EndedAt = DateTimeOffset.Now,
|
||||
Accuracy = 0.55879,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var unprocessedPPScore = new SoloScoreInfo
|
||||
@ -112,7 +134,26 @@ namespace osu.Game.Tests.Visual.Online
|
||||
Status = BeatmapOnlineStatus.Ranked,
|
||||
},
|
||||
EndedAt = DateTimeOffset.Now,
|
||||
Accuracy = 0.55879
|
||||
Accuracy = 0.55879,
|
||||
Ranked = true,
|
||||
};
|
||||
|
||||
var unrankedPPScore = new SoloScoreInfo
|
||||
{
|
||||
Rank = ScoreRank.B,
|
||||
Beatmap = new APIBeatmap
|
||||
{
|
||||
BeatmapSet = new APIBeatmapSet
|
||||
{
|
||||
Title = "C18H27NO3(extend)",
|
||||
Artist = "Team Grimoire",
|
||||
},
|
||||
DifficultyName = "[4K] Cataclysmic Hypernova",
|
||||
Status = BeatmapOnlineStatus.Ranked,
|
||||
},
|
||||
EndedAt = DateTimeOffset.Now,
|
||||
Accuracy = 0.55879,
|
||||
Ranked = false,
|
||||
};
|
||||
|
||||
Add(new FillFlowContainer
|
||||
@ -128,7 +169,9 @@ namespace osu.Game.Tests.Visual.Online
|
||||
new ColourProvidedContainer(OverlayColourScheme.Green, new DrawableProfileScore(firstScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Green, new DrawableProfileScore(secondScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(noPPScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(lovedScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(unprocessedPPScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(unrankedPPScore)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileWeightedScore(firstScore, 0.97)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileWeightedScore(secondScore, 0.85)),
|
||||
new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileWeightedScore(thirdScore, 0.66)),
|
||||
|
17
osu.Game/Graphics/Sprites/SpriteIconWithTooltip.cs
Normal file
17
osu.Game/Graphics/Sprites/SpriteIconWithTooltip.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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.Cursor;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
namespace osu.Game.Graphics.Sprites
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="SpriteIcon"/> with a publicly settable tooltip text.
|
||||
/// </summary>
|
||||
public partial class SpriteIconWithTooltip : SpriteIcon, IHasTooltip
|
||||
{
|
||||
public LocalisableString TooltipText { get; set; }
|
||||
}
|
||||
}
|
16
osu.Game/Graphics/Sprites/SpriteTextWithTooltip.cs
Normal file
16
osu.Game/Graphics/Sprites/SpriteTextWithTooltip.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// 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.Cursor;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
namespace osu.Game.Graphics.Sprites
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="OsuSpriteText"/> with a publicly settable tooltip text.
|
||||
/// </summary>
|
||||
internal partial class SpriteTextWithTooltip : OsuSpriteText, IHasTooltip
|
||||
{
|
||||
public LocalisableString TooltipText { get; set; }
|
||||
}
|
||||
}
|
@ -115,6 +115,9 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
[JsonProperty("has_replay")]
|
||||
public bool HasReplay { get; set; }
|
||||
|
||||
[JsonProperty("ranked")]
|
||||
public bool Ranked { get; set; }
|
||||
|
||||
// These properties are calculated or not relevant to any external usage.
|
||||
public bool ShouldSerializeID() => false;
|
||||
public bool ShouldSerializeUser() => false;
|
||||
@ -213,6 +216,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
HasOnlineReplay = HasReplay,
|
||||
Mods = mods,
|
||||
PP = PP,
|
||||
Ranked = Ranked,
|
||||
};
|
||||
|
||||
if (beatmap is BeatmapInfo realmBeatmap)
|
||||
|
@ -23,9 +23,9 @@ using osuTK.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Extensions.LocalisationExtensions;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring.Drawables;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
{
|
||||
@ -180,10 +180,26 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
||||
if (showPerformancePoints)
|
||||
{
|
||||
if (score.PP != null)
|
||||
content.Add(new StatisticText(score.PP, format: @"N0"));
|
||||
if (!score.Ranked)
|
||||
{
|
||||
content.Add(new SpriteTextWithTooltip
|
||||
{
|
||||
Text = "-",
|
||||
Font = OsuFont.GetFont(size: text_size),
|
||||
TooltipText = ScoresStrings.StatusNoPp
|
||||
});
|
||||
}
|
||||
else if (score.PP == null)
|
||||
{
|
||||
content.Add(new SpriteIconWithTooltip
|
||||
{
|
||||
Icon = FontAwesome.Solid.Sync,
|
||||
Size = new Vector2(text_size),
|
||||
TooltipText = ScoresStrings.StatusProcessing,
|
||||
});
|
||||
}
|
||||
else
|
||||
content.Add(new UnprocessedPerformancePointsPlaceholder { Size = new Vector2(text_size) });
|
||||
content.Add(new StatisticText(score.PP, format: @"N0"));
|
||||
}
|
||||
|
||||
content.Add(new ScoreboardTime(score.Date, text_size)
|
||||
|
@ -22,7 +22,6 @@ using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Scoring.Drawables;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
@ -125,10 +124,26 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
||||
ppColumn.Alpha = value.BeatmapInfo!.Status.GrantsPerformancePoints() ? 1 : 0;
|
||||
|
||||
if (value.PP is double pp)
|
||||
ppColumn.Text = pp.ToLocalisableString(@"N0");
|
||||
if (!value.Ranked)
|
||||
{
|
||||
ppColumn.Drawable = new SpriteTextWithTooltip
|
||||
{
|
||||
Text = "-",
|
||||
Font = smallFont,
|
||||
TooltipText = ScoresStrings.StatusNoPp
|
||||
};
|
||||
}
|
||||
else if (value.PP is not double pp)
|
||||
{
|
||||
ppColumn.Drawable = new SpriteIconWithTooltip
|
||||
{
|
||||
Icon = FontAwesome.Solid.Sync,
|
||||
Size = new Vector2(smallFont.Size),
|
||||
TooltipText = ScoresStrings.StatusProcessing,
|
||||
};
|
||||
}
|
||||
else
|
||||
ppColumn.Drawable = new UnprocessedPerformancePointsPlaceholder { Size = new Vector2(smallFont.Size) };
|
||||
ppColumn.Text = pp.ToLocalisableString(@"N0");
|
||||
|
||||
statisticsColumns.ChildrenEnumerable = value.GetStatisticsForDisplay().Select(createStatisticsColumn);
|
||||
modsColumn.Mods = value.Mods;
|
||||
|
@ -8,16 +8,17 @@ using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring.Drawables;
|
||||
using osu.Game.Utils;
|
||||
using osuTK;
|
||||
|
||||
@ -213,42 +214,75 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
|
||||
private Drawable createDrawablePerformance()
|
||||
{
|
||||
if (!Score.PP.HasValue)
|
||||
{
|
||||
if (Score.Beatmap?.Status.GrantsPerformancePoints() == true)
|
||||
return new UnprocessedPerformancePointsPlaceholder { Size = new Vector2(16), Colour = colourProvider.Highlight1 };
|
||||
var font = OsuFont.GetFont(weight: FontWeight.Bold);
|
||||
|
||||
return new OsuSpriteText
|
||||
if (Score.PP.HasValue)
|
||||
{
|
||||
return new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Font = font,
|
||||
Text = $"{Score.PP:0}",
|
||||
Colour = colourProvider.Highlight1
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Font = font.With(size: 12),
|
||||
Text = "pp",
|
||||
Colour = colourProvider.Light3
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (Score.Beatmap?.Status.GrantsPerformancePoints() != true)
|
||||
{
|
||||
if (Score.Beatmap?.Status == BeatmapOnlineStatus.Loved)
|
||||
{
|
||||
return new SpriteIconWithTooltip
|
||||
{
|
||||
Icon = FontAwesome.Solid.Heart,
|
||||
Size = new Vector2(font.Size),
|
||||
TooltipText = UsersStrings.ShowExtraTopRanksNotRanked,
|
||||
Colour = colourProvider.Highlight1
|
||||
};
|
||||
}
|
||||
|
||||
return new SpriteTextWithTooltip
|
||||
{
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
Text = "-",
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
TooltipText = UsersStrings.ShowExtraTopRanksNotRanked,
|
||||
Colour = colourProvider.Highlight1
|
||||
};
|
||||
}
|
||||
|
||||
return new FillFlowContainer
|
||||
if (!Score.Ranked)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
return new SpriteTextWithTooltip
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
Text = $"{Score.PP:0}",
|
||||
Colour = colourProvider.Highlight1
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
|
||||
Text = "pp",
|
||||
Colour = colourProvider.Light3
|
||||
}
|
||||
}
|
||||
Text = "-",
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
TooltipText = ScoresStrings.StatusNoPp,
|
||||
Colour = colourProvider.Highlight1
|
||||
};
|
||||
}
|
||||
|
||||
return new SpriteIconWithTooltip
|
||||
{
|
||||
Icon = FontAwesome.Solid.Sync,
|
||||
Size = new Vector2(font.Size),
|
||||
TooltipText = ScoresStrings.StatusProcessing,
|
||||
Colour = colourProvider.Highlight1
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,27 +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.
|
||||
|
||||
#nullable disable
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
|
||||
namespace osu.Game.Scoring.Drawables
|
||||
{
|
||||
/// <summary>
|
||||
/// A placeholder used in PP columns for scores with unprocessed PP value.
|
||||
/// </summary>
|
||||
public partial class UnprocessedPerformancePointsPlaceholder : SpriteIcon, IHasTooltip
|
||||
{
|
||||
public LocalisableString TooltipText => ScoresStrings.StatusProcessing;
|
||||
|
||||
public UnprocessedPerformancePointsPlaceholder()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
Icon = FontAwesome.Solid.ExclamationTriangle;
|
||||
}
|
||||
}
|
||||
}
|
@ -107,6 +107,12 @@ namespace osu.Game.Scoring
|
||||
|
||||
public double? PP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the performance points in this score is awarded to the player. This is used for online display purposes (see <see cref="SoloScoreInfo.Ranked"/>).
|
||||
/// </summary>
|
||||
[Ignored]
|
||||
public bool Ranked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The online ID of this score.
|
||||
/// </summary>
|
||||
|
@ -37,7 +37,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="11.5.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2024.205.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2024.129.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2024.207.0" />
|
||||
<PackageReference Include="Sentry" Version="3.41.3" />
|
||||
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
|
||||
<PackageReference Include="SharpCompress" Version="0.36.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user