1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-06 09:03:01 +08:00

Create a local playable beatmap instead

This commit is contained in:
smoogipoo 2020-06-22 18:38:41 +09:00
parent 9dbd230ad3
commit 261adfc4e6
9 changed files with 57 additions and 38 deletions

View File

@ -311,7 +311,7 @@ namespace osu.Game.Rulesets.Mania
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderByDescending(i => i).First(v => variant >= v); return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderByDescending(i => i).First(v => variant >= v);
} }
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[] public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{ {
new StatisticRow new StatisticRow
{ {

View File

@ -39,12 +39,12 @@ namespace osu.Game.Rulesets.Osu.Tests
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("#333"), Colour = Color4Extensions.FromHex("#333"),
}, },
object1 = new BorderCircle object2 = new BorderCircle
{ {
Position = new Vector2(256, 192), Position = new Vector2(256, 192),
Colour = Color4.Yellow, Colour = Color4.Yellow,
}, },
object2 = new BorderCircle object1 = new BorderCircle
{ {
Position = new Vector2(100, 300), Position = new Vector2(100, 300),
}, },
@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private class TestAccuracyHeatmap : AccuracyHeatmap private class TestAccuracyHeatmap : AccuracyHeatmap
{ {
public TestAccuracyHeatmap(ScoreInfo score) public TestAccuracyHeatmap(ScoreInfo score)
: base(score) : base(score, new TestBeatmap(new OsuRuleset().RulesetInfo))
{ {
} }

View File

@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Osu
public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo); public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new OsuRulesetConfigManager(settings, RulesetInfo);
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[] public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{ {
new StatisticRow new StatisticRow
{ {
@ -203,7 +203,7 @@ namespace osu.Game.Rulesets.Osu
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = 130 Height = 130
}), }),
new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score) new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap)
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = 130 Height = 130

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Scoring; using osu.Game.Scoring;
using osuTK; using osuTK;
@ -35,10 +36,12 @@ namespace osu.Game.Rulesets.Osu.Statistics
private GridContainer pointGrid; private GridContainer pointGrid;
private readonly ScoreInfo score; private readonly ScoreInfo score;
private readonly IBeatmap playableBeatmap;
public AccuracyHeatmap(ScoreInfo score) public AccuracyHeatmap(ScoreInfo score, IBeatmap playableBeatmap)
{ {
this.score = score; this.score = score;
this.playableBeatmap = playableBeatmap;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -146,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Statistics
return; return;
// Todo: This should probably not be done like this. // Todo: This should probably not be done like this.
float radius = OsuHitObject.OBJECT_RADIUS * (1.0f - 0.7f * (score.Beatmap.BaseDifficulty.CircleSize - 5) / 5) / 2; float radius = OsuHitObject.OBJECT_RADIUS * (1.0f - 0.7f * (playableBeatmap.BeatmapInfo.BaseDifficulty.CircleSize - 5) / 5) / 2;
foreach (var e in score.HitEvents.Where(e => e.HitObject is HitCircle)) foreach (var e in score.HitEvents.Where(e => e.HitObject is HitCircle))
{ {

View File

@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame();
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[] public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{ {
new StatisticRow new StatisticRow
{ {

View File

@ -214,8 +214,9 @@ namespace osu.Game.Rulesets
/// Creates the statistics for a <see cref="ScoreInfo"/> to be displayed in the results screen. /// Creates the statistics for a <see cref="ScoreInfo"/> to be displayed in the results screen.
/// </summary> /// </summary>
/// <param name="score">The <see cref="ScoreInfo"/> to create the statistics for. The score is guaranteed to have <see cref="ScoreInfo.HitEvents"/> populated.</param> /// <param name="score">The <see cref="ScoreInfo"/> to create the statistics for. The score is guaranteed to have <see cref="ScoreInfo.HitEvents"/> populated.</param>
/// <param name="playableBeatmap">The <see cref="IBeatmap"/>, converted for this <see cref="Ruleset"/> with all relevant <see cref="Mod"/>s applied.</param>
/// <returns>The <see cref="StatisticRow"/>s to display. Each <see cref="StatisticRow"/> may contain 0 or more <see cref="StatisticItem"/>.</returns> /// <returns>The <see cref="StatisticRow"/>s to display. Each <see cref="StatisticRow"/> may contain 0 or more <see cref="StatisticItem"/>.</returns>
[NotNull] [NotNull]
public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => Array.Empty<StatisticRow>(); public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty<StatisticRow>();
} }
} }

View File

@ -463,7 +463,7 @@ namespace osu.Game.Screens.Play
{ {
var score = new ScoreInfo var score = new ScoreInfo
{ {
Beatmap = gameplayBeatmap.BeatmapInfo, Beatmap = Beatmap.Value.BeatmapInfo,
Ruleset = rulesetInfo, Ruleset = rulesetInfo,
Mods = Mods.Value.ToArray(), Mods = Mods.Value.ToArray(),
}; };

View File

@ -31,8 +31,6 @@ namespace osu.Game.Screens.Play
var baseScore = base.CreateScore(); var baseScore = base.CreateScore();
// Since the replay score doesn't contain statistics, we'll pass them through here. // Since the replay score doesn't contain statistics, we'll pass them through here.
// We also have to pass in the beatmap to get the post-mod-application version.
score.ScoreInfo.Beatmap = baseScore.Beatmap;
score.ScoreInfo.HitEvents = baseScore.HitEvents; score.ScoreInfo.HitEvents = baseScore.HitEvents;
return score.ScoreInfo; return score.ScoreInfo;

View File

@ -1,14 +1,18 @@
// 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 System;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Placeholders; using osu.Game.Online.Placeholders;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring; using osu.Game.Scoring;
using osuTK; using osuTK;
@ -22,6 +26,9 @@ namespace osu.Game.Screens.Ranking.Statistics
protected override bool StartHidden => true; protected override bool StartHidden => true;
[Resolved]
private BeatmapManager beatmapManager { get; set; }
private readonly Container content; private readonly Container content;
private readonly LoadingSpinner spinner; private readonly LoadingSpinner spinner;
@ -71,37 +78,47 @@ namespace osu.Game.Screens.Ranking.Statistics
{ {
spinner.Show(); spinner.Show();
var rows = new FillFlowContainer var localCancellationSource = loadCancellation = new CancellationTokenSource();
{ IBeatmap playableBeatmap = null;
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(30, 15),
};
foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore)) // Todo: The placement of this is temporary. Eventually we'll both generate the playable beatmap _and_ run through it in a background task to generate the hit events.
Task.Run(() =>
{ {
rows.Add(new GridContainer playableBeatmap = beatmapManager.GetWorkingBeatmap(newScore.Beatmap).GetPlayableBeatmap(newScore.Ruleset, newScore.Mods ?? Array.Empty<Mod>());
}, loadCancellation.Token).ContinueWith(t =>
{
var rows = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.Both,
AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical,
Content = new[] Spacing = new Vector2(30, 15),
};
foreach (var row in newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap))
{
rows.Add(new GridContainer
{ {
row.Columns?.Select(c => new StatisticContainer(c)).Cast<Drawable>().ToArray() RelativeSizeAxes = Axes.X,
}, AutoSizeAxes = Axes.Y,
ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) Content = new[]
.Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), {
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } row.Columns?.Select(c => new StatisticContainer(c)).Cast<Drawable>().ToArray()
}); },
} ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0)
.Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(),
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }
});
}
LoadComponentAsync(rows, d => LoadComponentAsync(rows, d =>
{ {
if (Score.Value != newScore) if (Score.Value != newScore)
return; return;
spinner.Hide(); spinner.Hide();
content.Add(d); content.Add(d);
}, (loadCancellation = new CancellationTokenSource()).Token); }, localCancellationSource.Token);
}, localCancellationSource.Token);
} }
} }