Merge https://github.com/ppy/osu into multiplayer-room-settings

This commit is contained in:
DrabWeb
2018-06-06 00:19:23 -03:00
45 changed files with 434 additions and 273 deletions

View File

@ -182,9 +182,9 @@ namespace osu.Game.Screens.Edit
LoadComponentAsync(currentScreen, screenContainer.Add);
}
protected override bool OnWheel(InputState state)
protected override bool OnScroll(InputState state)
{
if (state.Mouse.WheelDelta > 0)
if (state.Mouse.ScrollDelta.X + state.Mouse.ScrollDelta.Y > 0)
clock.SeekBackward(true);
else
clock.SeekForward(true);

View File

@ -123,15 +123,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
/// </summary>
private float? localZoomTarget;
protected override bool OnWheel(InputState state)
protected override bool OnScroll(InputState state)
{
if (!state.Keyboard.ControlPressed)
return base.OnWheel(state);
return base.OnScroll(state);
relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X;
localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X;
Zoom += state.Mouse.WheelDelta;
Zoom += state.Mouse.ScrollDelta.Y;
return true;
}

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
@ -30,43 +29,48 @@ namespace osu.Game.Screens
{
base.LogoArriving(logo, resuming);
logo.BeatMatching = false;
logo.Triangles = false;
logo.Origin = Anchor.BottomRight;
logo.Anchor = Anchor.BottomRight;
logo.Position = new Vector2(-40);
logo.Scale = new Vector2(0.2f);
logo.FadeInFromZero(5000, Easing.OutQuint);
}
private OsuScreen loadScreen;
private ShaderPrecompiler precompiler;
protected override void OnEntering(Screen last)
{
base.OnEntering(last);
LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add);
LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady());
}
private void loadIfReady()
{
if (ChildScreen == loadScreen) return;
if (loadScreen.LoadState != LoadState.Ready)
return;
if (!precompiler.FinishedCompiling)
return;
Push(loadScreen);
logo.Delay(500).FadeInFromZero(1000, Easing.OutQuint);
}
protected override void LogoSuspending(OsuLogo logo)
{
base.LogoSuspending(logo);
logo.FadeOut(100);
logo.FadeOut(logo.Alpha * 400);
}
private OsuScreen loadableScreen;
private ShaderPrecompiler precompiler;
protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro();
protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler();
protected override void OnEntering(Screen last)
{
base.OnEntering(last);
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), Add);
LoadComponentAsync(loadableScreen = CreateLoadableScreen());
checkIfLoaded();
}
private void checkIfLoaded()
{
if (loadableScreen.LoadState != LoadState.Ready || !precompiler.FinishedCompiling)
{
Schedule(checkIfLoaded);
return;
}
Push(loadableScreen);
}
[BackgroundDependencyLoader]
@ -80,16 +84,10 @@ namespace osu.Game.Screens
/// </summary>
public class ShaderPrecompiler : Drawable
{
private readonly Action onLoaded;
private readonly List<Shader> loadTargets = new List<Shader>();
public bool FinishedCompiling { get; private set; }
public ShaderPrecompiler(Action onLoaded)
{
this.onLoaded = onLoaded;
}
[BackgroundDependencyLoader]
private void load(ShaderManager manager)
{
@ -103,16 +101,17 @@ namespace osu.Game.Screens
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
}
protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded);
protected override void Update()
{
base.Update();
// if our target is null we are done.
if (loadTargets.All(s => s.Loaded))
if (AllLoaded)
{
FinishedCompiling = true;
Expire();
onLoaded?.Invoke();
}
}
}

View File

@ -79,31 +79,6 @@ namespace osu.Game.Screens.Menu
seeya = audio.Sample.Get(@"seeya");
}
protected override void OnEntering(Screen last)
{
base.OnEntering(last);
Game.Beatmap.Value = beatmap;
if (menuVoice)
welcome.Play();
Scheduler.AddDelayed(delegate
{
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
if (menuMusic)
track.Start();
LoadComponentAsync(mainMenu = new MainMenu());
Scheduler.AddDelayed(delegate
{
DidLoadMenu = true;
Push(mainMenu);
}, delay_step_one);
}, delay_step_two);
}
private const double delay_step_one = 2300;
private const double delay_step_two = 600;
@ -113,6 +88,29 @@ namespace osu.Game.Screens.Menu
{
base.LogoArriving(logo, resuming);
if (!resuming)
{
Game.Beatmap.Value = beatmap;
if (menuVoice)
welcome.Play();
Scheduler.AddDelayed(delegate
{
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
if (menuMusic)
track.Start();
LoadComponentAsync(mainMenu = new MainMenu());
Scheduler.AddDelayed(delegate
{
DidLoadMenu = true;
Push(mainMenu);
}, delay_step_one);
}, delay_step_two);
}
logo.RelativePositionAxes = Axes.Both;
logo.Colour = Color4.White;
logo.Ripple = false;

View File

@ -24,8 +24,8 @@ namespace osu.Game.Screens.Menu
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private readonly Box leftBox;
private readonly Box rightBox;
private Box leftBox;
private Box rightBox;
private const float amplitude_dead_zone = 0.25f;
private const float alpha_multiplier = (1 - amplitude_dead_zone) / 0.55f;
@ -42,27 +42,6 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Children = new Drawable[]
{
leftBox = new Box
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
Blending = BlendingMode.Additive,
},
rightBox = new Box
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
Blending = BlendingMode.Additive,
}
};
}
[BackgroundDependencyLoader]
@ -72,10 +51,34 @@ namespace osu.Game.Screens.Menu
// linear colour looks better in this case, so let's use it for now.
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();
Color4 gradientLight = colours.Blue.Opacity(0.3f).ToLinear();
Color4 gradientLight = colours.Blue.Opacity(0.6f).ToLinear();
leftBox.Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark);
rightBox.Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight);
Children = new Drawable[]
{
leftBox = new Box
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y,
Width = box_width * 2,
// align off-screen to make sure our edges don't become visible during parallax.
X = -box_width,
Alpha = 0,
Blending = BlendingMode.Additive,
Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark)
},
rightBox = new Box
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Y,
Width = box_width * 2,
X = box_width,
Alpha = 0,
Blending = BlendingMode.Additive,
Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight)
}
};
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)

View File

@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu
set { colourAndTriangles.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint); }
}
public bool BeatMatching = true;
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => logoContainer.ReceiveMouseInputAt(screenSpacePos);
public bool Ripple
@ -264,6 +266,8 @@ namespace osu.Game.Screens.Menu
{
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
if (!BeatMatching) return;
lastBeatIndex = beatIndex;
var beatLength = timingPoint.BeatLength;

View File

@ -12,28 +12,23 @@ namespace osu.Game.Screens.Multi.Components
private const float text_size = 30;
private const float transition_duration = 100;
private readonly OsuSpriteText count, slash, max;
private readonly OsuSpriteText count, slash, maxText;
public int Count
{
set => count.Text = value.ToString();
}
private int? max;
public int? Max
{
get => max;
set
{
if (value == null)
{
slash.FadeOut(transition_duration);
max.FadeOut(transition_duration);
}
else
{
slash.FadeIn(transition_duration);
max.Text = value.ToString();
max.FadeIn(transition_duration);
}
if (value == max) return;
max = value;
updateMax();
}
}
@ -56,12 +51,29 @@ namespace osu.Game.Screens.Multi.Components
TextSize = text_size,
Font = @"Exo2.0-Light"
},
max = new OsuSpriteText
maxText = new OsuSpriteText
{
TextSize = text_size,
Font = @"Exo2.0-Light"
},
};
updateMax();
}
private void updateMax()
{
if (Max == null)
{
slash.FadeOut(transition_duration);
maxText.FadeOut(transition_duration);
}
else
{
slash.FadeIn(transition_duration);
maxText.Text = Max.ToString();
maxText.FadeIn(transition_duration);
}
}
}
}

View File

@ -225,6 +225,7 @@ namespace osu.Game.Screens
logo.Anchor = Anchor.TopLeft;
logo.Origin = Anchor.Centre;
logo.RelativePositionAxes = Axes.None;
logo.BeatMatching = true;
logo.Triangles = true;
logo.Ripple = true;
}

View File

@ -364,7 +364,7 @@ namespace osu.Game.Screens.Play
Background?.FadeTo(1f, fade_out_duration);
}
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
protected override bool OnScroll(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
private void initializeStoryboard(bool asyncLoad)
{

View File

@ -50,11 +50,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
}
button.FadeColour(expanded ? buttonActiveColour : Color4.White, 200, Easing.OutQuint);
updateExpanded();
}
}
private Color4 buttonActiveColour;
private Color4 expandedColour;
protected PlayerSettingsGroup()
{
@ -130,9 +130,13 @@ namespace osu.Game.Screens.Play.PlayerSettings
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
button.Colour = buttonActiveColour = colours.Yellow;
expandedColour = colours.Yellow;
updateExpanded();
}
private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint);
protected override Container<Drawable> Content => content;
protected override bool OnHover(InputState state) => true;

View File

@ -92,6 +92,6 @@ namespace osu.Game.Screens.Play
}
}
private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{timeSpan.Duration().TotalMinutes:N0}:{timeSpan.Duration().Seconds:D2}";
private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{Math.Floor(timeSpan.Duration().TotalMinutes)}:{timeSpan.Duration().Seconds:D2}";
}
}

View File

@ -6,7 +6,6 @@ using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System.Linq;
@ -120,14 +119,8 @@ namespace osu.Game.Screens.Select
Margin = new MarginPadding { Top = spacing * 2 },
Children = new[]
{
description = new MetadataSection("Description")
{
TextColour = Color4.White.Opacity(0.75f),
},
source = new MetadataSection("Source")
{
TextColour = Color4.White.Opacity(0.75f),
},
description = new MetadataSection("Description"),
source = new MetadataSection("Source"),
tags = new MetadataSection("Tags"),
},
},
@ -164,10 +157,9 @@ namespace osu.Game.Screens.Select
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, APIAccess api)
private void load(APIAccess api)
{
this.api = api;
tags.TextColour = colours.Yellow;
}
protected override void UpdateAfterChildren()
@ -364,7 +356,7 @@ namespace osu.Game.Screens.Select
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Colour = textFlow.Colour,
Colour = Color4.White.Opacity(0.75f),
Text = text
}, loaded =>
{
@ -375,12 +367,6 @@ namespace osu.Game.Screens.Select
this.FadeIn(transition_duration);
});
}
public Color4 TextColour
{
get { return textFlow.Colour; }
set { textFlow.Colour = value; }
}
}
private class DimmedLoadingAnimation : VisibilityContainer

View File

@ -57,7 +57,7 @@ namespace osu.Game.Screens.Select
{
if (osuGame != null)
ruleset.BindTo(osuGame.Ruleset);
ruleset.ValueChanged += updateRuleset;
ruleset.ValueChanged += _ => updateDisplay();
}
protected override bool BlockPassThroughMouse => false;
@ -78,66 +78,76 @@ namespace osu.Game.Screens.Select
private WorkingBeatmap beatmap;
public void UpdateBeatmap(WorkingBeatmap beatmap)
public WorkingBeatmap Beatmap
{
this.beatmap = beatmap;
loadBeatmap();
get => beatmap;
set
{
if (beatmap == value) return;
beatmap = value;
updateDisplay();
}
}
private void updateRuleset(RulesetInfo ruleset) => loadBeatmap();
private BufferedWedgeInfo loadingInfo;
private void loadBeatmap()
private void updateDisplay()
{
void updateState()
void removeOldInfo()
{
State = beatmap == null ? Visibility.Hidden : Visibility.Visible;
Info?.FadeOut(250);
Info?.Expire();
Info = null;
}
if (beatmap == null)
{
updateState();
removeOldInfo();
return;
}
LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value)
LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value)
{
Shear = -Shear,
Depth = Info?.Depth + 1 ?? 0,
}, newInfo =>
Depth = Info?.Depth + 1 ?? 0
}, loaded =>
{
updateState();
Add(Info = newInfo);
// ensure we are the most recent loaded wedge.
if (loaded != loadingInfo) return;
removeOldInfo();
Add(Info = loaded);
});
}
public class BufferedWedgeInfo : BufferedContainer
{
private readonly WorkingBeatmap working;
public OsuSpriteText VersionLabel { get; private set; }
public OsuSpriteText TitleLabel { get; private set; }
public OsuSpriteText ArtistLabel { get; private set; }
public FillFlowContainer MapperContainer { get; private set; }
public FillFlowContainer InfoLabelContainer { get; private set; }
private UnicodeBindableString titleBinding;
private UnicodeBindableString artistBinding;
private readonly WorkingBeatmap beatmap;
private readonly RulesetInfo ruleset;
public BufferedWedgeInfo(WorkingBeatmap working, RulesetInfo userRuleset)
public BufferedWedgeInfo(WorkingBeatmap beatmap, RulesetInfo userRuleset)
{
this.working = working;
ruleset = userRuleset ?? working.BeatmapInfo.Ruleset;
this.beatmap = beatmap;
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
}
[BackgroundDependencyLoader]
private void load(LocalisationEngine localisation)
{
var beatmapInfo = working.BeatmapInfo;
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
var beatmapInfo = beatmap.BeatmapInfo;
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
PixelSnapping = true;
CacheDrawnFrameBuffer = true;
@ -165,7 +175,7 @@ namespace osu.Game.Screens.Select
Children = new[]
{
// Zoomed-in and cropped beatmap background
new BeatmapBackgroundSprite(working)
new BeatmapBackgroundSprite(beatmap)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
@ -248,27 +258,27 @@ namespace osu.Game.Screens.Select
private InfoLabel[] getInfoLabels()
{
var beatmap = working.Beatmap;
var b = beatmap.Beatmap;
List<InfoLabel> labels = new List<InfoLabel>();
if (beatmap?.HitObjects?.Any() == true)
if (b?.HitObjects?.Any() == true)
{
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
HitObject lastObject = b.HitObjects.LastOrDefault();
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "Length",
Icon = FontAwesome.fa_clock_o,
Content = TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"),
}));
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "BPM",
Icon = FontAwesome.fa_circle,
Content = getBPMRange(beatmap),
Content = getBPMRange(b),
}));
IBeatmap playableBeatmap;
@ -276,12 +286,12 @@ namespace osu.Game.Screens.Select
try
{
// Try to get the beatmap with the user's ruleset
playableBeatmap = working.GetPlayableBeatmap(ruleset);
playableBeatmap = beatmap.GetPlayableBeatmap(ruleset);
}
catch (BeatmapInvalidForRulesetException)
{
// Can't be converted to the user's ruleset, so use the beatmap's own ruleset
playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset);
playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset);
}
labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)));

View File

@ -8,6 +8,7 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics;
@ -142,6 +143,8 @@ namespace osu.Game.Screens.Select.Leaderboards
{
flagBadgeContainer = new Container
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Size = new Vector2(87f, 20f),
Masking = true,
Children = new Drawable[]
@ -155,14 +158,16 @@ namespace osu.Game.Screens.Select.Leaderboards
},
new FillFlowContainer
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10f, 0f),
Margin = new MarginPadding { Left = edge_margin, },
Margin = new MarginPadding { Left = edge_margin },
Children = new Drawable[]
{
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()),
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy)),
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
},
},
},
@ -305,37 +310,61 @@ namespace osu.Game.Screens.Select.Leaderboards
}
}
private class ScoreComponentLabel : Container
private class ScoreComponentLabel : Container, IHasTooltip
{
public ScoreComponentLabel(FontAwesome icon, string value)
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
Size = new Vector2(60f, 20f);
Padding = new MarginPadding { Top = 10f, };
private const float icon_size = 20;
Children = new Drawable[]
private readonly string name;
private readonly FillFlowContainer content;
public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos);
public string TooltipText => name;
public ScoreComponentLabel(FontAwesome icon, string value, string name)
{
this.name = name;
AutoSizeAxes = Axes.Y;
Width = 60;
Child = content = new FillFlowContainer
{
new SpriteIcon
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new Drawable[]
{
Origin = Anchor.Centre,
Icon = FontAwesome.fa_square,
Colour = OsuColour.FromHex(@"3087ac"),
Rotation = 45,
Size = new Vector2(20),
Shadow = true,
},
new SpriteIcon
{
Origin = Anchor.Centre,
Icon = icon,
Colour = OsuColour.FromHex(@"a4edff"),
Size = new Vector2(14),
},
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
{
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 15, },
new Container
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
Children = new[]
{
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(icon_size),
Rotation = 45,
Colour = OsuColour.FromHex(@"3087ac"),
Icon = FontAwesome.fa_square,
Shadow = true,
},
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(icon_size - 6),
Colour = OsuColour.FromHex(@"a4edff"),
Icon = icon,
},
},
},
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
},
};
}

View File

@ -430,7 +430,7 @@ namespace osu.Game.Screens.Select
backgroundModeBeatmap.FadeTo(1, 250);
}
beatmapInfoWedge.UpdateBeatmap(beatmap);
beatmapInfoWedge.Beatmap = beatmap;
}
private void ensurePlayingSelected(bool preview = false)