1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +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);
}
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[]
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{
new StatisticRow
{

View File

@ -39,12 +39,12 @@ namespace osu.Game.Rulesets.Osu.Tests
RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("#333"),
},
object1 = new BorderCircle
object2 = new BorderCircle
{
Position = new Vector2(256, 192),
Colour = Color4.Yellow,
},
object2 = new BorderCircle
object1 = new BorderCircle
{
Position = new Vector2(100, 300),
},
@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private class TestAccuracyHeatmap : AccuracyHeatmap
{
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 StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[]
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{
new StatisticRow
{
@ -203,7 +203,7 @@ namespace osu.Game.Rulesets.Osu
RelativeSizeAxes = Axes.X,
Height = 130
}),
new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score)
new StatisticItem("Accuracy Heatmap", new AccuracyHeatmap(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
Height = 130

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Scoring;
using osuTK;
@ -35,10 +36,12 @@ namespace osu.Game.Rulesets.Osu.Statistics
private GridContainer pointGrid;
private readonly ScoreInfo score;
private readonly IBeatmap playableBeatmap;
public AccuracyHeatmap(ScoreInfo score)
public AccuracyHeatmap(ScoreInfo score, IBeatmap playableBeatmap)
{
this.score = score;
this.playableBeatmap = playableBeatmap;
}
[BackgroundDependencyLoader]
@ -146,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Statistics
return;
// 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))
{

View File

@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame();
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score) => new[]
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{
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.
/// </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="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>
[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
{
Beatmap = gameplayBeatmap.BeatmapInfo,
Beatmap = Beatmap.Value.BeatmapInfo,
Ruleset = rulesetInfo,
Mods = Mods.Value.ToArray(),
};

View File

@ -31,8 +31,6 @@ namespace osu.Game.Screens.Play
var baseScore = base.CreateScore();
// 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;
return score.ScoreInfo;

View File

@ -1,14 +1,18 @@
// 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;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Placeholders;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osuTK;
@ -22,6 +26,9 @@ namespace osu.Game.Screens.Ranking.Statistics
protected override bool StartHidden => true;
[Resolved]
private BeatmapManager beatmapManager { get; set; }
private readonly Container content;
private readonly LoadingSpinner spinner;
@ -71,37 +78,47 @@ namespace osu.Game.Screens.Ranking.Statistics
{
spinner.Show();
var rows = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(30, 15),
};
var localCancellationSource = loadCancellation = new CancellationTokenSource();
IBeatmap playableBeatmap = null;
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,
AutoSizeAxes = Axes.Y,
Content = new[]
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
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()
},
ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0)
.Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(),
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }
});
}
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Content = new[]
{
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 =>
{
if (Score.Value != newScore)
return;
LoadComponentAsync(rows, d =>
{
if (Score.Value != newScore)
return;
spinner.Hide();
content.Add(d);
}, (loadCancellation = new CancellationTokenSource()).Token);
spinner.Hide();
content.Add(d);
}, localCancellationSource.Token);
}, localCancellationSource.Token);
}
}