Merge branch 'master' of https://github.com/ppy/osu into intro-improvements

This commit is contained in:
ColdVolcano
2017-04-24 22:42:28 -05:00
43 changed files with 651 additions and 337 deletions

View File

@ -38,8 +38,6 @@ namespace osu.Game.Screens.Play
protected override void Update()
{
base.Update();
if (parentClock == null) return;
clock.Rate = parentClock.Rate;

View File

@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select
{
beatmap = value;
Leaderboard.Beatmap = beatmap?.BeatmapInfo;
Details.Beatmap = beatmap?.Beatmap.BeatmapInfo;
Details.Beatmap = beatmap?.BeatmapInfo;
}
}
@ -66,16 +66,16 @@ namespace osu.Game.Screens.Select
{
Details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(5),
RelativeSizeAxes = Axes.X,
Masking = true,
Height = 352,
Alpha = 0,
},
Leaderboard = new Leaderboard
{
RelativeSizeAxes = Axes.Both,
}
});
}
}
}
}

View File

@ -4,10 +4,12 @@
using System;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
@ -21,15 +23,22 @@ namespace osu.Game.Screens.Select
public Action<BeatmapDetailTab, bool> OnFilter; //passed the selected tab and if mods is checked
private Bindable<BeatmapDetailTab> selectedTab;
private void invokeOnFilter()
{
OnFilter?.Invoke(tabs.Current, modsCheckbox.Current);
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
private void load(OsuColour colour, OsuConfigManager config)
{
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
selectedTab = config.GetBindable<BeatmapDetailTab>(OsuConfig.BeatmapDetailTab);
tabs.Current.BindTo(selectedTab);
tabs.Current.TriggerChange();
}
public BeatmapDetailAreaTabControl()
@ -62,8 +71,6 @@ namespace osu.Game.Screens.Select
tabs.Current.ValueChanged += item => invokeOnFilter();
modsCheckbox.Current.ValueChanged += item => invokeOnFilter();
tabs.Current.Value = BeatmapDetailTab.Global;
}
}

View File

@ -14,6 +14,9 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System.Globalization;
using System.Linq;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Framework.Threading;
namespace osu.Game.Screens.Select
{
@ -39,60 +42,108 @@ namespace osu.Game.Screens.Select
private readonly BarGraph retryGraph;
private readonly BarGraph failGraph;
private ScheduledDelegate pendingBeatmapSwitch;
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get
{
return beatmap;
}
get { return beatmap; }
set
{
beatmap = value;
if (beatmap == null) return;
description.Text = beatmap.Version;
source.Text = beatmap.Metadata.Source;
tags.Text = beatmap.Metadata.Tags;
circleSize.Value = beatmap.Difficulty.CircleSize;
drainRate.Value = beatmap.Difficulty.DrainRate;
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
approachRate.Value = beatmap.Difficulty.ApproachRate;
stars.Value = (float)beatmap.StarDifficulty;
if (beatmap.Metrics?.Ratings.Any() ?? false)
{
var ratings = beatmap.Metrics.Ratings.ToList();
ratingsContainer.Show();
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
ratingsGraph.Values = ratings.Select(rating => (float)rating);
}
else
ratingsContainer.Hide();
if ((beatmap.Metrics?.Retries.Any() ?? false) && beatmap.Metrics.Fails.Any())
{
var retries = beatmap.Metrics.Retries;
var fails = beatmap.Metrics.Fails;
retryFailContainer.Show();
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
failGraph.MaxValue = maxValue;
retryGraph.MaxValue = maxValue;
failGraph.Values = fails.Select(fail => (float)fail);
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
}
else
retryFailContainer.Hide();
pendingBeatmapSwitch?.Cancel();
pendingBeatmapSwitch = Schedule(updateStats);
}
}
private void updateStats()
{
if (beatmap == null) return;
description.Text = beatmap.Version;
source.Text = beatmap.Metadata.Source;
tags.Text = beatmap.Metadata.Tags;
circleSize.Value = beatmap.Difficulty.CircleSize;
drainRate.Value = beatmap.Difficulty.DrainRate;
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
approachRate.Value = beatmap.Difficulty.ApproachRate;
stars.Value = (float)beatmap.StarDifficulty;
var requestedBeatmap = beatmap;
if (requestedBeatmap.Metrics == null)
{
var lookup = new GetBeatmapDetailsRequest(requestedBeatmap);
lookup.Success += res =>
{
if (beatmap != requestedBeatmap)
//the beatmap has been changed since we started the lookup.
return;
requestedBeatmap.Metrics = res;
Schedule(() => updateMetrics(res));
};
lookup.Failure += e => updateMetrics(null);
api.Queue(lookup);
}
updateMetrics(requestedBeatmap.Metrics, false);
}
/// <summary>
/// Update displayed metrics.
/// </summary>
/// <param name="metrics">New metrics to overwrite the existing display. Can be null.</param>
/// <param name="failOnMissing">Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates.</param>
private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true)
{
var hasRatings = metrics?.Ratings.Any() ?? false;
var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any();
if (hasRatings)
{
var ratings = metrics.Ratings.ToList();
ratingsContainer.Show();
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
ratingsGraph.Values = ratings.Select(rating => (float)rating);
ratingsContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
}
else if (failOnMissing)
ratingsGraph.Values = new float[10];
else
ratingsContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
if (hasRetriesFails)
{
var retries = metrics.Retries;
var fails = metrics.Fails;
retryFailContainer.Show();
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
failGraph.MaxValue = maxValue;
retryGraph.MaxValue = maxValue;
failGraph.Values = fails.Select(fail => (float)fail);
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
retryFailContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
}
else if (failOnMissing)
{
failGraph.Values = new float[100];
retryGraph.Values = new float[100];
}
else
retryFailContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
}
public BeatmapDetails()
{
Children = new Drawable[]
@ -113,7 +164,6 @@ namespace osu.Game.Screens.Select
Direction = FillDirection.Vertical,
LayoutDuration = 200,
LayoutEasing = EasingTypes.OutQuint,
Padding = new MarginPadding(10) { Top = 25 },
Children = new []
{
description = new MetadataSegment("Description"),
@ -148,8 +198,8 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0,10),
Padding = new MarginPadding(15) { Top = 25 },
Spacing = new Vector2(0,5),
Padding = new MarginPadding(10),
Children = new []
{
circleSize = new DifficultyRow("Circle Size", 7),
@ -252,7 +302,7 @@ namespace osu.Game.Screens.Select
new Container<BarGraph>
{
RelativeSizeAxes = Axes.X,
Size = new Vector2(1/0.6f, 50),
Size = new Vector2(1 / 0.6f, 50),
Children = new[]
{
retryGraph = new BarGraph
@ -272,9 +322,13 @@ namespace osu.Game.Screens.Select
};
}
private APIAccess api;
[BackgroundDependencyLoader]
private void load(OsuColour colour)
private void load(OsuColour colour, APIAccess api)
{
this.api = api;
description.AccentColour = colour.GrayB;
source.AccentColour = colour.GrayB;
tags.AccentColour = colour.YellowLight;
@ -308,7 +362,7 @@ namespace osu.Game.Screens.Select
{
difficultyValue = value;
bar.Length = value / maxValue;
valueText.Text = value.ToString(CultureInfo.InvariantCulture);
valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture);
}
}
@ -431,4 +485,4 @@ namespace osu.Game.Screens.Select
}
}
}
}
}

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
@ -148,11 +149,16 @@ namespace osu.Game.Screens.Select
},
},
},
// Text for beatmap info
new DifficultyColourBar(beatmap.BeatmapInfo)
{
RelativeSizeAxes = Axes.Y,
Width = 20,
},
new FillFlowContainer
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Name = "Top-aligned metadata",
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 },
AutoSizeAxes = Axes.Both,
@ -161,16 +167,32 @@ namespace osu.Game.Screens.Select
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = metadata.Artist + " -- " + metadata.Title,
Text = beatmapInfo.Version,
TextSize = 24,
},
}
},
new FillFlowContainer
{
Name = "Bottom-aligned metadata",
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title,
TextSize = 28,
Shadow = true,
},
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = beatmapInfo.Version,
Text = metadata.Artist,
TextSize = 17,
Shadow = true,
},
new FillFlowContainer
{
@ -184,20 +206,18 @@ namespace osu.Game.Screens.Select
Font = @"Exo2.0-Medium",
Text = "mapped by ",
TextSize = 15,
Shadow = true,
},
},
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = metadata.Author,
TextSize = 15,
Shadow = true,
},
},
}
},
new FillFlowContainer
{
Margin = new MarginPadding { Top = 20 },
Margin = new MarginPadding { Top = 20, Left = 10 },
Spacing = new Vector2(40, 0),
AutoSizeAxes = Axes.Both,
Children = labels
@ -256,5 +276,37 @@ namespace osu.Game.Screens.Select
};
}
}
private class DifficultyColourBar : DifficultyColouredContainer
{
public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap)
{
}
[BackgroundDependencyLoader]
private void load()
{
const float full_opacity_ratio = 0.7f;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = AccentColour,
Width = full_opacity_ratio,
},
new Box
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
Colour = AccentColour,
Alpha = 0.5f,
X = full_opacity_ratio,
Width = 1 - full_opacity_ratio,
}
};
}
}
}
}

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using System;
using osu.Framework.Allocation;
using osu.Framework.Threading;
using osu.Game.Database;
using osu.Game.Rulesets.Scoring;
using osu.Game.Online.API;
@ -93,13 +94,18 @@ namespace osu.Game.Screens.Select.Leaderboards
private BeatmapInfo beatmap;
private ScheduledDelegate pendingBeatmapSwitch;
public BeatmapInfo Beatmap
{
get { return beatmap; }
set
{
beatmap = value;
Schedule(updateScores);
Scores = null;
pendingBeatmapSwitch?.Cancel();
pendingBeatmapSwitch = Schedule(updateScores);
}
}