diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 16f0af9875..efa23f1a26 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -105,13 +105,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double approachRateFactor = 1.0f;
if (Attributes.ApproachRate > 10.33f)
- approachRateFactor += 0.45f * (Attributes.ApproachRate - 10.33f);
+ approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
else if (Attributes.ApproachRate < 8.0f)
{
- // HD is worth more with lower ar!
- if (mods.Any(h => h is OsuModHidden))
- approachRateFactor += 0.02f * (8.0f - Attributes.ApproachRate);
- else
approachRateFactor += 0.01f * (8.0f - Attributes.ApproachRate);
}
@@ -119,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
if (mods.Any(h => h is OsuModHidden))
- aimValue *= 1.02 + (11.0f - Attributes.ApproachRate) / 50.0; // Gives a 1.04 bonus for AR10, a 1.06 bonus for AR9, a 1.02 bonus for AR11.
+ aimValue *= 1.0f + 0.04f * (12.0f - Attributes.ApproachRate);
if (mods.Any(h => h is OsuModFlashlight))
{
@@ -152,13 +148,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (beatmapMaxCombo > 0)
speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
+ double approachRateFactor = 1.0f;
+ if (Attributes.ApproachRate > 10.33f)
+ approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
+
+ speedValue *= approachRateFactor;
+
if (mods.Any(m => m is OsuModHidden))
- speedValue *= 1.18f;
+ speedValue *= 1.0f + 0.04f * (12.0f - Attributes.ApproachRate);
// Scale the speed value with accuracy _slightly_
- speedValue *= 0.5f + accuracy / 2.0f;
+ speedValue *= 0.02f + accuracy;
// It is important to also consider accuracy difficulty when doing that
- speedValue *= 0.98f + Math.Pow(Attributes.OverallDifficulty, 2) / 2500;
+ speedValue *= 0.96f + Math.Pow(Attributes.OverallDifficulty, 2) / 1600;
return speedValue;
}
@@ -186,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
accuracyValue *= Math.Min(1.15f, Math.Pow(amountHitObjectsWithAccuracy / 1000.0f, 0.3f));
if (mods.Any(m => m is OsuModHidden))
- accuracyValue *= 1.02f;
+ accuracyValue *= 1.08f;
if (mods.Any(m => m is OsuModFlashlight))
accuracyValue *= 1.02f;
diff --git a/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs b/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
index cf475de1f0..821bf84047 100644
--- a/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
+++ b/osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
@@ -17,12 +17,13 @@ namespace osu.Game.Tests.Visual
{
public TestCaseMatchLeaderboard()
{
- Add(new MatchLeaderboard(new Room { RoomID = { Value = 3 } })
+ Add(new MatchLeaderboard
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f),
Scope = MatchLeaderboardScope.Overall,
+ Room = new Room { RoomID = { Value = 3 } }
});
}
diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs
index 0534fd9253..6ad5b2070e 100644
--- a/osu.Game/Beatmaps/BeatmapInfo.cs
+++ b/osu.Game/Beatmaps/BeatmapInfo.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
+using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
@@ -9,6 +10,7 @@ using Newtonsoft.Json;
using osu.Game.Database;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets;
+using osu.Game.Scoring;
namespace osu.Game.Beatmaps
{
@@ -112,6 +114,11 @@ namespace osu.Game.Beatmaps
[JsonProperty("difficulty_rating")]
public double StarDifficulty { get; set; }
+ ///
+ /// Currently only populated for beatmap deletion. Use to query scores.
+ ///
+ public List Scores { get; set; }
+
public override string ToString() => $"{Metadata} [{Version}]";
public bool Equals(BeatmapInfo other)
diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs
index 5bdc42cdf3..6817c0653d 100644
--- a/osu.Game/Beatmaps/BeatmapStore.cs
+++ b/osu.Game/Beatmaps/BeatmapStore.cs
@@ -64,7 +64,8 @@ namespace osu.Game.Beatmaps
base.AddIncludesForDeletion(query)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
- .Include(s => s.Metadata);
+ .Include(s => s.Metadata)
+ .Include(s => s.Beatmaps).ThenInclude(b => b.Scores);
protected override IQueryable AddIncludesForConsumption(IQueryable query) =>
base.AddIncludesForConsumption(query)
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 8df286ffb2..1b279eee44 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -105,6 +105,8 @@ namespace osu.Game.Configuration
Set(OsuSetting.ScalingPositionX, 0.5f, 0f, 1f);
Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f);
+
+ Set(OsuSetting.UIScale, 1f, 0.8f, 1.6f, 0.01f);
}
public OsuConfigManager(Storage storage)
@@ -167,6 +169,7 @@ namespace osu.Game.Configuration
ScalingPositionX,
ScalingPositionY,
ScalingSizeX,
- ScalingSizeY
+ ScalingSizeY,
+ UIScale
}
}
diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs
index 74315d2522..e4c18dfb3d 100644
--- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs
+++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs
@@ -79,6 +79,7 @@ namespace osu.Game.Graphics.Containers
{
AddInternal(new DrawableLinkCompiler(drawables.OfType().ToList())
{
+ RelativeSizeAxes = Axes.Both,
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
Action = action ?? (() =>
{
@@ -122,5 +123,10 @@ namespace osu.Game.Graphics.Containers
}),
});
}
+
+ // We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
+ // However due to https://github.com/ppy/osu-framework/issues/2073, it's possible for the compilers to be relative size in the flow's auto-size axes - an unsupported operation.
+ // Since the compilers don't display any content and don't affect the layout, it's simplest to exclude them from the flow.
+ public override IEnumerable FlowingChildren => base.FlowingChildren.Where(c => !(c is DrawableLinkCompiler));
}
}
diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs
index ff7a1cdacf..8d21d6de10 100644
--- a/osu.Game/Graphics/Containers/ScalingContainer.cs
+++ b/osu.Game/Graphics/Containers/ScalingContainer.cs
@@ -46,10 +46,37 @@ namespace osu.Game.Graphics.Containers
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
CornerRadius = 10,
- Child = content = new DrawSizePreservingFillContainer()
+ Child = content = new ScalingDrawSizePreservingFillContainer(targetMode != ScalingMode.Gameplay)
};
}
+ private class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer
+ {
+ private readonly bool applyUIScale;
+ private Bindable uiScale;
+
+ public ScalingDrawSizePreservingFillContainer(bool applyUIScale)
+ {
+ this.applyUIScale = applyUIScale;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuConfigManager osuConfig)
+ {
+ if (applyUIScale)
+ {
+ uiScale = osuConfig.GetBindable(OsuSetting.UIScale);
+ uiScale.BindValueChanged(scaleChanged, true);
+ }
+ }
+
+ private void scaleChanged(float value)
+ {
+ this.ScaleTo(new Vector2(value), 500, Easing.Out);
+ this.ResizeTo(new Vector2(1 / value), 500, Easing.Out);
+ }
+ }
+
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
index 10b83c2610..2bd84ab2b4 100644
--- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
+++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
@@ -8,7 +8,6 @@ using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
-using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Graphics.Cursor;
@@ -33,38 +32,7 @@ namespace osu.Game.Graphics.UserInterface
private readonly Box leftBox;
private readonly Box rightBox;
- public virtual string TooltipText
- {
- get
- {
- var bindableDouble = CurrentNumber as BindableNumber;
- var bindableFloat = CurrentNumber as BindableNumber;
- var floatValue = bindableDouble?.Value ?? bindableFloat?.Value;
- var floatPrecision = bindableDouble?.Precision ?? bindableFloat?.Precision;
-
- if (floatValue != null)
- {
- var floatMinValue = bindableDouble?.MinValue ?? bindableFloat.MinValue;
- var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue;
-
- if (floatMaxValue == 1 && floatMinValue >= -1)
- return floatValue.Value.ToString("P0");
-
- var decimalPrecision = normalise((decimal)floatPrecision, max_decimal_digits);
-
- // Find the number of significant digits (we could have less than 5 after normalize())
- var significantDigits = findPrecision(decimalPrecision);
-
- return floatValue.Value.ToString($"N{significantDigits}");
- }
-
- var bindableInt = CurrentNumber as BindableNumber;
- if (bindableInt != null)
- return bindableInt.Value.ToString("N0");
-
- return Current.Value.ToString(CultureInfo.InvariantCulture);
- }
- }
+ public virtual string TooltipText { get; private set; }
private Color4 accentColour;
public Color4 AccentColour
@@ -136,21 +104,34 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(e);
}
- protected override void OnUserChange()
+ protected override bool OnMouseDown(MouseDownEvent e)
{
- base.OnUserChange();
- playSample();
+ Nub.Current.Value = true;
+ return base.OnMouseDown(e);
}
- private void playSample()
+ protected override bool OnMouseUp(MouseUpEvent e)
+ {
+ Nub.Current.Value = false;
+ return base.OnMouseUp(e);
+ }
+
+ protected override void OnUserChange(T value)
+ {
+ base.OnUserChange(value);
+ playSample(value);
+ updateTooltipText(value);
+ }
+
+ private void playSample(T value)
{
if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
return;
- if (Current.Value.Equals(lastSampleValue))
+ if (value.Equals(lastSampleValue))
return;
- lastSampleValue = Current.Value;
+ lastSampleValue = value;
lastSampleTime = Clock.CurrentTime;
sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
@@ -163,16 +144,28 @@ namespace osu.Game.Graphics.UserInterface
sample.Play();
}
- protected override bool OnMouseDown(MouseDownEvent e)
+ private void updateTooltipText(T value)
{
- Nub.Current.Value = true;
- return base.OnMouseDown(e);
- }
+ if (CurrentNumber.IsInteger)
+ TooltipText = ((int)Convert.ChangeType(value, typeof(int))).ToString("N0");
+ else
+ {
+ double floatValue = (double)Convert.ChangeType(value, typeof(double));
+ double floatMinValue = (double)Convert.ChangeType(CurrentNumber.MinValue, typeof(double));
+ double floatMaxValue = (double)Convert.ChangeType(CurrentNumber.MaxValue, typeof(double));
- protected override bool OnMouseUp(MouseUpEvent e)
- {
- Nub.Current.Value = false;
- return base.OnMouseUp(e);
+ if (floatMaxValue == 1 && floatMinValue >= -1)
+ TooltipText = floatValue.ToString("P0");
+ else
+ {
+ var decimalPrecision = normalise((decimal)Convert.ChangeType(CurrentNumber.Precision, typeof(decimal)), max_decimal_digits);
+
+ // Find the number of significant digits (we could have less than 5 after normalize())
+ var significantDigits = findPrecision(decimalPrecision);
+
+ TooltipText = floatValue.ToString($"N{significantDigits}");
+ }
+ }
}
protected override void UpdateAfterChildren()
diff --git a/osu.Game/Graphics/UserInterface/ProgressBar.cs b/osu.Game/Graphics/UserInterface/ProgressBar.cs
index ee64c7c25c..6dca58f70d 100644
--- a/osu.Game/Graphics/UserInterface/ProgressBar.cs
+++ b/osu.Game/Graphics/UserInterface/ProgressBar.cs
@@ -62,6 +62,6 @@ namespace osu.Game.Graphics.UserInterface
fill.Width = value * UsableWidth;
}
- protected override void OnUserChange() => OnSeek?.Invoke(Current);
+ protected override void OnUserChange(double value) => OnSeek?.Invoke(value);
}
}
diff --git a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs
index 8026847e3b..2dafedc3ac 100644
--- a/osu.Game/Migrations/OsuDbContextModelSnapshot.cs
+++ b/osu.Game/Migrations/OsuDbContextModelSnapshot.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
+ .HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
{
@@ -215,6 +215,25 @@ namespace osu.Game.Migrations
b.ToTable("Settings");
});
+ modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
+ {
+ b.Property("ID")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Hash");
+
+ b.Property("ReferenceCount");
+
+ b.HasKey("ID");
+
+ b.HasIndex("Hash")
+ .IsUnique();
+
+ b.HasIndex("ReferenceCount");
+
+ b.ToTable("FileInfo");
+ });
+
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
{
b.Property("ID")
@@ -239,25 +258,6 @@ namespace osu.Game.Migrations
b.ToTable("KeyBinding");
});
- modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd();
-
- b.Property("Hash");
-
- b.Property("ReferenceCount");
-
- b.HasKey("ID");
-
- b.HasIndex("Hash")
- .IsUnique();
-
- b.HasIndex("ReferenceCount");
-
- b.ToTable("FileInfo");
- });
-
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
{
b.Property("ID")
@@ -454,7 +454,7 @@ namespace osu.Game.Migrations
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
- .WithMany()
+ .WithMany("Scores")
.HasForeignKey("BeatmapInfoID")
.OnDelete(DeleteBehavior.Cascade);
diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs
index 10b4e73419..db273dd00a 100644
--- a/osu.Game/Online/API/APIAccess.cs
+++ b/osu.Game/Online/API/APIAccess.cs
@@ -101,6 +101,9 @@ namespace osu.Game.Online.API
//todo: replace this with a ping request.
log.Add(@"In a failing state, waiting a bit before we try again...");
Thread.Sleep(5000);
+
+ if (!IsLoggedIn) goto case APIState.Connecting;
+
if (queue.Count == 0)
{
log.Add(@"Queueing a ping request");
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index bb356ce7f0..58af93a88b 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -359,7 +359,10 @@ namespace osu.Game
{
RelativeSizeAxes = Axes.Both,
},
- mainContent = new DrawSizePreservingFillContainer(),
+ mainContent = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
idleTracker = new IdleTracker(6000)
});
diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
index 3fa4276616..d59e2e033e 100644
--- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
@@ -63,9 +63,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
},
+ new SettingsSlider
+ {
+ LabelText = "UI Scaling",
+ TransferValueOnCommit = true,
+ Bindable = osuConfig.GetBindable(OsuSetting.UIScale),
+ KeyboardStep = 0.01f
+ },
new SettingsEnumDropdown
{
- LabelText = "Scaling",
+ LabelText = "Screen Scaling",
Bindable = osuConfig.GetBindable(OsuSetting.Scaling),
},
scalingSettings = new FillFlowContainer>
@@ -202,6 +209,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
}
}
+ private class UIScaleSlider : OsuSliderBar
+ {
+ public override string TooltipText => base.TooltipText + "x";
+ }
+
private class ResolutionSettingsDropdown : SettingsDropdown
{
protected override OsuDropdown CreateDropdown() => new ResolutionDropdownControl { Items = Items };
diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
index aa63b02013..373f4d1682 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
@@ -238,11 +238,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
case Key.Right:
beatDivisor.Next();
- OnUserChange();
+ OnUserChange(Current);
return true;
case Key.Left:
beatDivisor.Previous();
- OnUserChange();
+ OnUserChange(Current);
return true;
default:
return false;
@@ -279,7 +279,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
var xPosition = (ToLocalSpace(screenSpaceMousePosition).X - RangePadding) / UsableWidth;
CurrentNumber.Value = availableDivisors.OrderBy(d => Math.Abs(getMappedPosition(d) - xPosition)).First();
- OnUserChange();
+ OnUserChange(Current);
}
private float getMappedPosition(float divisor) => (float)Math.Pow((divisor - 1) / (availableDivisors.Last() - 1), 0.90f);
diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs
index 47f5182c39..63730ff635 100644
--- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs
+++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using System.Linq;
+using System;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
@@ -13,8 +13,9 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
-using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
using osu.Game.Online.Multiplayer;
using osu.Game.Screens.Multi.Components;
using osu.Game.Users;
@@ -37,11 +38,10 @@ namespace osu.Game.Screens.Multi.Lounge.Components
private Box statusStrip;
private UpdateableBeatmapBackgroundSprite background;
private ParticipantCountDisplay participantCount;
- private FillFlowContainer topFlow, participantsFlow;
private OsuSpriteText name, status;
private BeatmapTypeInfo beatmapTypeInfo;
- private ScrollContainer participantsScroll;
private ParticipantInfo participantInfo;
+ private MatchParticipants participants;
[Resolved]
private BeatmapManager beatmaps { get; set; }
@@ -58,141 +58,141 @@ namespace osu.Game.Screens.Multi.Lounge.Components
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"343138"),
},
- topFlow = new FillFlowContainer
+ new GridContainer
{
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
- Children = new Drawable[]
+ RelativeSizeAxes = Axes.Both,
+ RowDimensions = new[]
{
- new Container
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(GridSizeMode.Distributed),
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- RelativeSizeAxes = Axes.X,
- Height = 200,
- Masking = true,
- Children = new Drawable[]
+ new FillFlowContainer
{
- background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both },
- new Box
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.5f), Color4.Black.Opacity(0)),
- },
- new Container
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(20),
- Children = new Drawable[]
+ new Container
{
- participantCount = new ParticipantCountDisplay
+ RelativeSizeAxes = Axes.X,
+ Height = 200,
+ Masking = true,
+ Children = new Drawable[]
{
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
+ background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both },
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.5f), Color4.Black.Opacity(0)),
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(20),
+ Children = new Drawable[]
+ {
+ participantCount = new ParticipantCountDisplay
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ },
+ name = new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ TextSize = 30,
+ },
+ },
+ },
},
- name = new OsuSpriteText
+ },
+ statusStrip = new Box
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 5,
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new Drawable[]
{
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.BottomLeft,
- TextSize = 30,
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.FromHex(@"28242d"),
+ },
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ LayoutDuration = transition_duration,
+ Padding = contentPadding,
+ Spacing = new Vector2(0f, 5f),
+ Children = new Drawable[]
+ {
+ status = new OsuSpriteText
+ {
+ TextSize = 14,
+ Font = @"Exo2.0-Bold",
+ },
+ beatmapTypeInfo = new BeatmapTypeInfo(),
+ },
+ },
+ },
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Padding = contentPadding,
+ Children = new Drawable[]
+ {
+ participantInfo = new ParticipantInfo(),
},
},
},
},
},
- statusStrip = new Box
+ new Drawable[]
{
- RelativeSizeAxes = Axes.X,
- Height = 5,
- },
- new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Children = new Drawable[]
+ participants = new MatchParticipants
{
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.FromHex(@"28242d"),
- },
- new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
- LayoutDuration = transition_duration,
- Padding = contentPadding,
- Spacing = new Vector2(0f, 5f),
- Children = new Drawable[]
- {
- status = new OsuSpriteText
- {
- TextSize = 14,
- Font = @"Exo2.0-Bold",
- },
- beatmapTypeInfo = new BeatmapTypeInfo(),
- },
- },
- },
- },
- new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Padding = contentPadding,
- Children = new Drawable[]
- {
- participantInfo = new ParticipantInfo(),
- },
- },
- },
- },
- participantsScroll = new OsuScrollContainer
- {
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.BottomLeft,
- RelativeSizeAxes = Axes.X,
- Padding = new MarginPadding { Top = contentPadding.Top, Left = 38, Right = 37 },
- Children = new[]
- {
- participantsFlow = new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- LayoutDuration = transition_duration,
- Spacing = new Vector2(5f),
- },
- },
- },
+ RelativeSizeAxes = Axes.Both,
+ }
+ }
+ }
+ }
};
participantInfo.Host.BindTo(bindings.Host);
participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount);
participantInfo.Participants.BindTo(bindings.Participants);
-
participantCount.Participants.BindTo(bindings.Participants);
participantCount.ParticipantCount.BindTo(bindings.ParticipantCount);
participantCount.MaxParticipants.BindTo(bindings.MaxParticipants);
-
beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
beatmapTypeInfo.Type.BindTo(bindings.Type);
background.Beatmap.BindTo(bindings.CurrentBeatmap);
-
bindings.Status.BindValueChanged(displayStatus);
- bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)));
bindings.Name.BindValueChanged(n => name.Text = n);
-
Room.BindValueChanged(updateRoom, true);
}
private void updateRoom(Room room)
{
bindings.Room = room;
+ participants.Room = room;
if (room != null)
{
- participantsFlow.FadeIn(transition_duration);
participantCount.FadeIn(transition_duration);
beatmapTypeInfo.FadeIn(transition_duration);
name.FadeIn(transition_duration);
@@ -200,7 +200,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components
}
else
{
- participantsFlow.FadeOut(transition_duration);
participantCount.FadeOut(transition_duration);
beatmapTypeInfo.FadeOut(transition_duration);
name.FadeOut(transition_duration);
@@ -210,13 +209,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components
}
}
- protected override void UpdateAfterChildren()
- {
- base.UpdateAfterChildren();
-
- participantsScroll.Height = DrawHeight - topFlow.DrawHeight;
- }
-
private void displayStatus(RoomStatus s)
{
status.Text = s.Message;
@@ -226,39 +218,113 @@ namespace osu.Game.Screens.Multi.Lounge.Components
status.FadeColour(c, transition_duration);
}
- private class UserTile : Container, IHasTooltip
- {
- private readonly User user;
-
- public string TooltipText => user.Username;
-
- public UserTile(User user)
- {
- this.user = user;
- Size = new Vector2(70f);
- CornerRadius = 5f;
- Masking = true;
-
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.FromHex(@"27252d"),
- },
- new UpdateableAvatar
- {
- RelativeSizeAxes = Axes.Both,
- User = user,
- },
- };
- }
- }
-
private class RoomStatusNoneSelected : RoomStatus
{
public override string Message => @"No Room Selected";
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray8;
}
+
+ private class MatchParticipants : CompositeDrawable
+ {
+ private Room room;
+ private readonly FillFlowContainer fill;
+
+ public Room Room
+ {
+ get { return room; }
+ set
+ {
+ if (room == value)
+ return;
+
+ room = value;
+ updateParticipants();
+ }
+ }
+
+ public MatchParticipants()
+ {
+ Padding = new MarginPadding { Horizontal = 10 };
+
+ InternalChild = new ScrollContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = fill = new FillFlowContainer
+ {
+ Spacing = new Vector2(10),
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Full,
+ }
+ };
+ }
+
+ [Resolved]
+ private APIAccess api { get; set; }
+
+ private GetRoomScoresRequest request;
+
+ private void updateParticipants()
+ {
+ var roomId = room.RoomID.Value ?? 0;
+
+ request?.Cancel();
+
+ // nice little progressive fade
+ int time = 500;
+ foreach (var c in fill.Children)
+ {
+ c.Delay(500 - time).FadeOut(time, Easing.Out);
+ time = Math.Max(20, time - 20);
+ c.Expire();
+ }
+
+ if (roomId == 0) return;
+
+ request = new GetRoomScoresRequest(roomId);
+ request.Success += scores =>
+ {
+ if (roomId != room.RoomID.Value)
+ return;
+
+ fill.Clear();
+ foreach (var s in scores)
+ fill.Add(new UserTile(s.User));
+
+ fill.FadeInFromZero(1000, Easing.OutQuint);
+ };
+
+ api.Queue(request);
+ }
+
+ private class UserTile : CompositeDrawable, IHasTooltip
+ {
+ private readonly User user;
+
+ public string TooltipText => user.Username;
+
+ public UserTile(User user)
+ {
+ this.user = user;
+ Size = new Vector2(70f);
+ CornerRadius = 5f;
+ Masking = true;
+
+ InternalChildren = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.FromHex(@"27252d"),
+ },
+ new UpdateableAvatar
+ {
+ RelativeSizeAxes = Axes.Both,
+ User = user,
+ },
+ };
+ }
+ }
+ }
}
}
diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs
index 864191105f..5ac0453373 100644
--- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs
+++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboard.cs
@@ -16,17 +16,18 @@ namespace osu.Game.Screens.Multi.Match.Components
{
public Action> ScoresLoaded;
- private readonly Room room;
-
- public MatchLeaderboard(Room room)
+ public Room Room
{
- this.room = room;
+ get => bindings.Room;
+ set => bindings.Room = value;
}
+ private readonly RoomBindings bindings = new RoomBindings();
+
[BackgroundDependencyLoader]
private void load()
{
- room.RoomID.BindValueChanged(id =>
+ bindings.RoomID.BindValueChanged(id =>
{
if (id == null)
return;
@@ -38,10 +39,10 @@ namespace osu.Game.Screens.Multi.Match.Components
protected override APIRequest FetchScores(Action> scoresCallback)
{
- if (room.RoomID == null)
+ if (bindings.RoomID.Value == null)
return null;
- var req = new GetRoomScoresRequest(room.RoomID.Value ?? 0);
+ var req = new GetRoomScoresRequest(bindings.RoomID.Value ?? 0);
req.Success += r =>
{
diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs
index 55a5a2c85e..14cdd90128 100644
--- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs
+++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs
@@ -71,10 +71,11 @@ namespace osu.Game.Screens.Multi.Match
{
new Drawable[]
{
- leaderboard = new MatchLeaderboard(room)
+ leaderboard = new MatchLeaderboard
{
Padding = new MarginPadding(10),
- RelativeSizeAxes = Axes.Both
+ RelativeSizeAxes = Axes.Both,
+ Room = room
},
new Container
{
diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs
index 54528e5503..44f5f11c93 100644
--- a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs
+++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs
@@ -103,8 +103,8 @@ namespace osu.Game.Screens.Multi.Ranking.Pages
public class ResultsMatchLeaderboard : MatchLeaderboard
{
public ResultsMatchLeaderboard(Room room)
- : base(room)
{
+ Room = room;
}
protected override bool FadeTop => true;
diff --git a/osu.Game/Screens/Multi/RoomBindings.cs b/osu.Game/Screens/Multi/RoomBindings.cs
index cdbb6dbea6..30e2918b69 100644
--- a/osu.Game/Screens/Multi/RoomBindings.cs
+++ b/osu.Game/Screens/Multi/RoomBindings.cs
@@ -39,6 +39,7 @@ namespace osu.Game.Screens.Multi
if (room != null)
{
+ RoomID.UnbindFrom(room.RoomID);
Name.UnbindFrom(room.Name);
Host.UnbindFrom(room.Host);
Status.UnbindFrom(room.Status);
@@ -56,6 +57,7 @@ namespace osu.Game.Screens.Multi
if (room != null)
{
+ RoomID.BindTo(room.RoomID);
Name.BindTo(room.Name);
Host.BindTo(room.Host);
Status.BindTo(room.Status);
@@ -82,6 +84,7 @@ namespace osu.Game.Screens.Multi
currentRuleset.Value = playlistItem?.Ruleset;
}
+ public readonly Bindable RoomID = new Bindable();
public readonly Bindable Name = new Bindable();
public readonly Bindable Host = new Bindable();
public readonly Bindable Status = new Bindable();
diff --git a/osu.Game/Screens/Play/SongProgressBar.cs b/osu.Game/Screens/Play/SongProgressBar.cs
index 1f0c4936a5..b06a34e603 100644
--- a/osu.Game/Screens/Play/SongProgressBar.cs
+++ b/osu.Game/Screens/Play/SongProgressBar.cs
@@ -112,6 +112,6 @@ namespace osu.Game.Screens.Play
handleBase.X = xFill;
}
- protected override void OnUserChange() => OnSeek?.Invoke(Current);
+ protected override void OnUserChange(double value) => OnSeek?.Invoke(value);
}
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index d6dbb6f11c..8f00e81237 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -18,7 +18,7 @@
-
+