mirror of https://github.com/ppy/osu
Merge remote-tracking branch 'refs/remotes/ppy/master' into friends-layout-split
This commit is contained in:
commit
4d376636c3
|
@ -52,6 +52,6 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.317.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -417,7 +417,7 @@ public async Task TestImportWhenFileOpen()
|
|||
[Test]
|
||||
public async Task TestImportWithDuplicateHashes()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportNestedStructure)))
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithDuplicateHashes)))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Users;
|
||||
|
@ -203,7 +204,7 @@ public void PauseTest()
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the visual settings container removes user dim when suspending <see cref="Player"/> for <see cref="SoloResults"/>
|
||||
/// Check if the visual settings container removes user dim when suspending <see cref="Player"/> for <see cref="ResultsScreen"/>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TransitionTest()
|
||||
|
@ -335,7 +336,7 @@ private void load(OsuConfigManager config)
|
|||
public bool IsBackgroundCurrent() => ((FadeAccessibleBackground)Background).IsCurrentScreen();
|
||||
}
|
||||
|
||||
private class FadeAccessibleResults : SoloResults
|
||||
private class FadeAccessibleResults : ResultsScreen
|
||||
{
|
||||
public FadeAccessibleResults(ScoreInfo score)
|
||||
: base(score)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Screens.Multi.Ranking;
|
||||
using osu.Game.Screens.Multi.Ranking.Pages;
|
||||
using osu.Game.Screens.Multi.Ranking.Types;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneMatchResults : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MatchResults),
|
||||
typeof(RoomLeaderboardPageInfo),
|
||||
typeof(RoomLeaderboardPage)
|
||||
};
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||
if (beatmapInfo != null)
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||
|
||||
Room.RoomID.Value = 1;
|
||||
Room.Name.Value = "an awesome room";
|
||||
|
||||
LoadScreen(new TestMatchResults(new ScoreInfo
|
||||
{
|
||||
User = new User { Id = 10 },
|
||||
}));
|
||||
}
|
||||
|
||||
private class TestMatchResults : MatchResults
|
||||
{
|
||||
public TestMatchResults(ScoreInfo score)
|
||||
: base(score)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap.Value) };
|
||||
}
|
||||
|
||||
private class TestRoomLeaderboardPageInfo : RoomLeaderboardPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public TestRoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public override ResultsPage CreatePage() => new TestRoomLeaderboardPage(score, beatmap);
|
||||
}
|
||||
|
||||
private class TestRoomLeaderboardPage : RoomLeaderboardPage
|
||||
{
|
||||
public TestRoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MatchLeaderboard CreateLeaderboard() => new TestMatchLeaderboard();
|
||||
}
|
||||
|
||||
private class TestMatchLeaderboard : RoomLeaderboardPage.ResultsMatchLeaderboard
|
||||
{
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<APIUserScoreAggregate>> scoresCallback)
|
||||
{
|
||||
var scores = Enumerable.Range(0, 50).Select(createRoomScore).ToArray();
|
||||
|
||||
scoresCallback?.Invoke(scores);
|
||||
ScoresLoaded?.Invoke(scores);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private APIUserScoreAggregate createRoomScore(int id) => new APIUserScoreAggregate
|
||||
{
|
||||
User = new User { Id = id, Username = $"User {id}" },
|
||||
Accuracy = 0.98,
|
||||
TotalScore = 987654,
|
||||
TotalAttempts = 13,
|
||||
CompletedBeatmaps = 5
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
// 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.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
public class TestSceneAccuracyCircle : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(AccuracyCircle),
|
||||
typeof(RankBadge),
|
||||
typeof(RankNotch),
|
||||
typeof(RankText),
|
||||
typeof(SmoothCircularProgress)
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestDRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.5;
|
||||
score.Rank = ScoreRank.D;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.75;
|
||||
score.Rank = ScoreRank.C;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.85;
|
||||
score.Rank = ScoreRank.B;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestARank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.925;
|
||||
score.Rank = ScoreRank.A;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.975;
|
||||
score.Rank = ScoreRank.S;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAlmostSSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.9999;
|
||||
score.Rank = ScoreRank.S;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 1;
|
||||
score.Rank = ScoreRank.X;
|
||||
|
||||
addCircleStep(score);
|
||||
}
|
||||
|
||||
private void addCircleStep(ScoreInfo score) => AddStep("add panel", () =>
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 700),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#555"), Color4Extensions.FromHex("#333"))
|
||||
}
|
||||
}
|
||||
},
|
||||
new AccuracyCircle(score)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(230)
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
private ScoreInfo createScore() => new ScoreInfo
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 2,
|
||||
Username = "peppy",
|
||||
},
|
||||
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
|
||||
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||
TotalScore = 2845370,
|
||||
Accuracy = 0.95,
|
||||
MaxCombo = 999,
|
||||
Rank = ScoreRank.S,
|
||||
Date = DateTimeOffset.Now,
|
||||
Statistics =
|
||||
{
|
||||
{ HitResult.Miss, 1 },
|
||||
{ HitResult.Meh, 50 },
|
||||
{ HitResult.Good, 100 },
|
||||
{ HitResult.Great, 300 },
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// 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.Collections.Generic;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Expanded;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osu.Game.Screens.Ranking.Expanded.Statistics;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
public class TestSceneExpandedPanelMiddleContent : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ExpandedPanelMiddleContent),
|
||||
typeof(AccuracyCircle),
|
||||
typeof(AccuracyStatistic),
|
||||
typeof(ComboStatistic),
|
||||
typeof(CounterStatistic),
|
||||
typeof(StarRatingDisplay),
|
||||
typeof(StatisticDisplay),
|
||||
typeof(TotalScoreCounter)
|
||||
};
|
||||
|
||||
public TestSceneExpandedPanelMiddleContent()
|
||||
{
|
||||
Child = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 700),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#444"),
|
||||
},
|
||||
new ExpandedPanelMiddleContent(createTestScore())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ScoreInfo createTestScore() => new ScoreInfo
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 2,
|
||||
Username = "peppy",
|
||||
},
|
||||
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
|
||||
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||
TotalScore = 999999,
|
||||
Accuracy = 0.95,
|
||||
MaxCombo = 999,
|
||||
Rank = ScoreRank.S,
|
||||
Date = DateTimeOffset.Now,
|
||||
Statistics =
|
||||
{
|
||||
{ HitResult.Miss, 1 },
|
||||
{ HitResult.Meh, 50 },
|
||||
{ HitResult.Good, 100 },
|
||||
{ HitResult.Great, 300 },
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// 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 osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens.Ranking.Expanded;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
public class TestSceneExpandedPanelTopContent : OsuTestScene
|
||||
{
|
||||
public TestSceneExpandedPanelTopContent()
|
||||
{
|
||||
Child = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 200),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#444"),
|
||||
},
|
||||
new ExpandedPanelTopContent(new User { Id = 2, Username = "peppy" }),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,29 +10,27 @@
|
|||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneResults : ScreenTestScene
|
||||
public class TestSceneResultsScreen : ScreenTestScene
|
||||
{
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Results),
|
||||
typeof(ResultsPage),
|
||||
typeof(ScoreResultsPage),
|
||||
typeof(ResultsScreen),
|
||||
typeof(RetryButton),
|
||||
typeof(ReplayDownloadButton),
|
||||
typeof(LocalLeaderboardPage),
|
||||
typeof(TestPlayer)
|
||||
};
|
||||
|
||||
|
@ -65,6 +63,7 @@ protected override void LoadComplete()
|
|||
{ HitResult.Meh, 50 },
|
||||
{ HitResult.Miss, 1 }
|
||||
},
|
||||
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
|
||||
User = new User
|
||||
{
|
||||
Username = "peppy",
|
||||
|
@ -119,7 +118,7 @@ public TestResultsContainer(IScreen screen)
|
|||
}
|
||||
}
|
||||
|
||||
private class TestSoloResults : SoloResults
|
||||
private class TestSoloResults : ResultsScreen
|
||||
{
|
||||
public HotkeyRetryOverlay RetryOverlay;
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
// 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.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Expanded;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
public class TestSceneScorePanel : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ScorePanel),
|
||||
typeof(PanelState),
|
||||
typeof(ExpandedPanelMiddleContent),
|
||||
typeof(ExpandedPanelTopContent),
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestDRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.5;
|
||||
score.Rank = ScoreRank.D;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.75;
|
||||
score.Rank = ScoreRank.C;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.85;
|
||||
score.Rank = ScoreRank.B;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestARank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.925;
|
||||
score.Rank = ScoreRank.A;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.975;
|
||||
score.Rank = ScoreRank.S;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAlmostSSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 0.9999;
|
||||
score.Rank = ScoreRank.S;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSSRank()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Accuracy = 1;
|
||||
score.Rank = ScoreRank.X;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAllHitResults()
|
||||
{
|
||||
var score = createScore();
|
||||
score.Statistics[HitResult.Perfect] = 350;
|
||||
score.Statistics[HitResult.Ok] = 200;
|
||||
|
||||
addPanelStep(score);
|
||||
}
|
||||
|
||||
private void addPanelStep(ScoreInfo score) => AddStep("add panel", () =>
|
||||
{
|
||||
Child = new ScorePanel(score)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
State = PanelState.Expanded
|
||||
};
|
||||
});
|
||||
|
||||
private ScoreInfo createScore() => new ScoreInfo
|
||||
{
|
||||
User = new User
|
||||
{
|
||||
Id = 2,
|
||||
Username = "peppy",
|
||||
},
|
||||
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo,
|
||||
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||
TotalScore = 2845370,
|
||||
Accuracy = 0.95,
|
||||
MaxCombo = 999,
|
||||
Rank = ScoreRank.S,
|
||||
Date = DateTimeOffset.Now,
|
||||
Statistics =
|
||||
{
|
||||
{ HitResult.Miss, 1 },
|
||||
{ HitResult.Meh, 50 },
|
||||
{ HitResult.Good, 100 },
|
||||
{ HitResult.Great, 300 },
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// 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 osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Ranking.Expanded;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Ranking
|
||||
{
|
||||
public class TestSceneStarRatingDisplay : OsuTestScene
|
||||
{
|
||||
public TestSceneStarRatingDisplay()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 1.23 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 2.34 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 3.45 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 4.56 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 5.67 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 6.78 }),
|
||||
new StarRatingDisplay(new BeatmapInfo { StarDifficulty = 10.11 }),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// 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.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Components
|
||||
{
|
||||
public class TestSceneRoundDisplay : TournamentTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(DrawableTournamentHeaderText),
|
||||
typeof(DrawableTournamentHeaderLogo),
|
||||
};
|
||||
|
||||
public TestSceneRoundDisplay()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new RoundDisplay(new TournamentMatch
|
||||
{
|
||||
Round =
|
||||
{
|
||||
Value = new TournamentRound
|
||||
{
|
||||
Name = { Value = "Test Round" }
|
||||
}
|
||||
}
|
||||
})
|
||||
{
|
||||
Margin = new MarginPadding(20)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,9 +11,13 @@ namespace osu.Game.Tournament.Components
|
|||
{
|
||||
public class DrawableTournamentHeaderText : CompositeDrawable
|
||||
{
|
||||
public DrawableTournamentHeaderText()
|
||||
public DrawableTournamentHeaderText(bool center = true)
|
||||
{
|
||||
InternalChild = new TextSprite();
|
||||
InternalChild = new TextSprite
|
||||
{
|
||||
Anchor = center ? Anchor.Centre : Anchor.TopLeft,
|
||||
Origin = center ? Anchor.Centre : Anchor.TopLeft,
|
||||
};
|
||||
|
||||
Height = 22;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
@ -27,9 +31,6 @@ private void load(TextureStore textures)
|
|||
RelativeSizeAxes = Axes.Both;
|
||||
FillMode = FillMode.Fit;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Texture = textures.Get("header-text");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,19 +12,27 @@ public class RoundDisplay : CompositeDrawable
|
|||
{
|
||||
public RoundDisplay(TournamentMatch match)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTournamentHeaderText(),
|
||||
new DrawableTournamentHeaderText(false)
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = OsuFont.Torus.With(size: 26, weight: FontWeight.SemiBold)
|
||||
},
|
||||
|
|
|
@ -35,7 +35,9 @@ public TeamScoreDisplay(TeamColour teamColour)
|
|||
private void load(LadderInfo ladder)
|
||||
{
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
currentMatch.BindValueChanged(matchChanged, true);
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
|
||||
updateMatch();
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
|
||||
|
@ -43,10 +45,19 @@ private void matchChanged(ValueChangedEvent<TournamentMatch> match)
|
|||
currentTeamScore.UnbindBindings();
|
||||
currentTeam.UnbindBindings();
|
||||
|
||||
if (match.NewValue != null)
|
||||
Scheduler.AddOnce(updateMatch);
|
||||
}
|
||||
|
||||
private void updateMatch()
|
||||
{
|
||||
var match = currentMatch.Value;
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score);
|
||||
currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2);
|
||||
match.StartMatch();
|
||||
|
||||
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.Team1Score : match.Team2Score);
|
||||
currentTeam.BindTo(teamColour == TeamColour.Red ? match.Team1 : match.Team2);
|
||||
}
|
||||
|
||||
// team may change to same team, which means score is not in a good state.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Collections.Generic;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
|
@ -60,8 +61,9 @@ public interface IWorkingBeatmap
|
|||
/// </summary>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <param name="timeout">The maximum length in milliseconds to wait for load to complete. Defaults to 10,000ms.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null);
|
||||
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,55 +83,81 @@ protected virtual Track GetVirtualTrack(double emptyLength = 0)
|
|||
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
|
||||
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
|
||||
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null)
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null)
|
||||
{
|
||||
mods ??= Array.Empty<Mod>();
|
||||
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
||||
IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);
|
||||
|
||||
// Check if the beatmap can be converted
|
||||
if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert())
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).");
|
||||
|
||||
// Apply conversion mods
|
||||
foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
|
||||
// Convert
|
||||
IBeatmap converted = converter.Convert();
|
||||
|
||||
// Apply difficulty mods
|
||||
if (mods.Any(m => m is IApplicableToDifficulty))
|
||||
using (var cancellationSource = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(10)))
|
||||
{
|
||||
converted.BeatmapInfo = converted.BeatmapInfo.Clone();
|
||||
converted.BeatmapInfo.BaseDifficulty = converted.BeatmapInfo.BaseDifficulty.Clone();
|
||||
mods ??= Array.Empty<Mod>();
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
||||
IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted);
|
||||
IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);
|
||||
|
||||
processor?.PreProcess();
|
||||
// Check if the beatmap can be converted
|
||||
if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert())
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).");
|
||||
|
||||
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
||||
foreach (var obj in converted.HitObjects)
|
||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
|
||||
// Apply conversion mods
|
||||
foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())
|
||||
{
|
||||
if (cancellationSource.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject>())
|
||||
{
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
}
|
||||
|
||||
// Convert
|
||||
IBeatmap converted = converter.Convert();
|
||||
|
||||
// Apply difficulty mods
|
||||
if (mods.Any(m => m is IApplicableToDifficulty))
|
||||
{
|
||||
converted.BeatmapInfo = converted.BeatmapInfo.Clone();
|
||||
converted.BeatmapInfo.BaseDifficulty = converted.BeatmapInfo.BaseDifficulty.Clone();
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToDifficulty>())
|
||||
{
|
||||
if (cancellationSource.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
}
|
||||
|
||||
IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted);
|
||||
|
||||
processor?.PreProcess();
|
||||
|
||||
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
||||
foreach (var obj in converted.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
{
|
||||
if (cancellationSource.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject>())
|
||||
{
|
||||
foreach (var obj in converted.HitObjects)
|
||||
{
|
||||
if (cancellationSource.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
mod.ApplyToHitObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
processor?.PostProcess();
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToBeatmap>())
|
||||
{
|
||||
cancellationSource.Token.ThrowIfCancellationRequested();
|
||||
mod.ApplyToBeatmap(converted);
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
processor?.PostProcess();
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToBeatmap>())
|
||||
mod.ApplyToBeatmap(converted);
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
private CancellationTokenSource loadCancellation = new CancellationTokenSource();
|
||||
|
@ -297,5 +323,13 @@ public T Value
|
|||
|
||||
private void recreate() => lazy = new Lazy<T>(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
}
|
||||
|
||||
private class BeatmapLoadTimeoutException : TimeoutException
|
||||
{
|
||||
public BeatmapLoadTimeoutException(BeatmapInfo beatmapInfo)
|
||||
: base($"Timed out while loading beatmap ({beatmapInfo}).")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics
|
||||
|
@ -37,6 +38,35 @@ public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterCo
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the colour for a <see cref="ScoreRank"/>.
|
||||
/// </summary>
|
||||
public static Color4 ForRank(ScoreRank rank)
|
||||
{
|
||||
switch (rank)
|
||||
{
|
||||
case ScoreRank.XH:
|
||||
case ScoreRank.X:
|
||||
return Color4Extensions.FromHex(@"ce1c9d");
|
||||
|
||||
case ScoreRank.SH:
|
||||
case ScoreRank.S:
|
||||
return Color4Extensions.FromHex(@"00a8b5");
|
||||
|
||||
case ScoreRank.A:
|
||||
return Color4Extensions.FromHex(@"7cce14");
|
||||
|
||||
case ScoreRank.B:
|
||||
return Color4Extensions.FromHex(@"e3b130");
|
||||
|
||||
case ScoreRank.C:
|
||||
return Color4Extensions.FromHex(@"f18252");
|
||||
|
||||
default:
|
||||
return Color4Extensions.FromHex(@"e95353");
|
||||
}
|
||||
}
|
||||
|
||||
// See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less
|
||||
public readonly Color4 PurpleLighter = Color4Extensions.FromHex(@"eeeeff");
|
||||
public readonly Color4 PurpleLight = Color4Extensions.FromHex(@"aa88ff");
|
||||
|
|
|
@ -43,6 +43,18 @@ public ColourInfo GlowColour
|
|||
set => blurredText.Colour = value;
|
||||
}
|
||||
|
||||
public Vector2 Spacing
|
||||
{
|
||||
get => spriteText.Spacing;
|
||||
set => spriteText.Spacing = blurredText.Spacing = value;
|
||||
}
|
||||
|
||||
public bool UseFullGlyphHeight
|
||||
{
|
||||
get => spriteText.UseFullGlyphHeight;
|
||||
set => spriteText.UseFullGlyphHeight = blurredText.UseFullGlyphHeight = value;
|
||||
}
|
||||
|
||||
public GlowingSpriteText()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
|
|
@ -28,7 +28,7 @@ public DrawableRank(ScoreRank rank)
|
|||
FillMode = FillMode.Fit;
|
||||
FillAspectRatio = 2;
|
||||
|
||||
var rankColour = getRankColour();
|
||||
var rankColour = OsuColour.ForRank(rank);
|
||||
InternalChild = new DrawSizePreservingFillContainer
|
||||
{
|
||||
TargetDrawSize = new Vector2(64, 32),
|
||||
|
@ -59,7 +59,7 @@ public DrawableRank(ScoreRank rank)
|
|||
Padding = new MarginPadding { Top = 5 },
|
||||
Colour = getRankNameColour(),
|
||||
Font = OsuFont.Numeric.With(size: 25),
|
||||
Text = getRankName(),
|
||||
Text = GetRankName(rank),
|
||||
ShadowColour = Color4.Black.Opacity(0.3f),
|
||||
ShadowOffset = new Vector2(0, 0.08f),
|
||||
Shadow = true,
|
||||
|
@ -69,36 +69,7 @@ public DrawableRank(ScoreRank rank)
|
|||
};
|
||||
}
|
||||
|
||||
private string getRankName() => rank.GetDescription().TrimEnd('+');
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the grade background colour.
|
||||
/// </summary>
|
||||
private Color4 getRankColour()
|
||||
{
|
||||
switch (rank)
|
||||
{
|
||||
case ScoreRank.XH:
|
||||
case ScoreRank.X:
|
||||
return Color4Extensions.FromHex(@"ce1c9d");
|
||||
|
||||
case ScoreRank.SH:
|
||||
case ScoreRank.S:
|
||||
return Color4Extensions.FromHex(@"00a8b5");
|
||||
|
||||
case ScoreRank.A:
|
||||
return Color4Extensions.FromHex(@"7cce14");
|
||||
|
||||
case ScoreRank.B:
|
||||
return Color4Extensions.FromHex(@"e3b130");
|
||||
|
||||
case ScoreRank.C:
|
||||
return Color4Extensions.FromHex(@"f18252");
|
||||
|
||||
default:
|
||||
return Color4Extensions.FromHex(@"e95353");
|
||||
}
|
||||
}
|
||||
public static string GetRankName(ScoreRank rank) => rank.GetDescription().TrimEnd('+');
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the grade text colour.
|
||||
|
|
|
@ -148,7 +148,7 @@ public DateContainer(DateTime date)
|
|||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.GetFont(Typeface.Torus, 12, FontWeight.Black, false, false),
|
||||
Font = OsuFont.GetFont(Typeface.Torus, 12, FontWeight.Bold, false, false),
|
||||
Text = date.ToString("d MMM yyy").ToUpper(),
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
|
|
|
@ -84,13 +84,13 @@ private void load(OsuColour colours)
|
|||
new OsuSpriteText
|
||||
{
|
||||
Text = titleText.ToUpperInvariant(),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Black)
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
||||
},
|
||||
countDrawable = new OsuSpriteText
|
||||
{
|
||||
Text = "3",
|
||||
Colour = colours.Yellow,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Black)
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -53,7 +53,7 @@ protected Toast(string description, string value, string shortcut)
|
|||
{
|
||||
Padding = new MarginPadding(10),
|
||||
Name = "Description",
|
||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black),
|
||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
|
||||
Spacing = new Vector2(1, 0),
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
|
|
|
@ -59,7 +59,7 @@ private void load(OverlayColourProvider colourProvider, OsuColour colours)
|
|||
new OsuSpriteText
|
||||
{
|
||||
Text = MainText,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black),
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
|
|
|
@ -80,7 +80,7 @@ public void APIStateChanged(IAPIProvider api, APIState state) => Schedule(() =>
|
|||
{
|
||||
Text = "ACCOUNT",
|
||||
Margin = new MarginPadding { Bottom = 5 },
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Black),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
},
|
||||
form = new LoginForm
|
||||
{
|
||||
|
|
|
@ -54,7 +54,7 @@ private void load()
|
|||
{
|
||||
Text = Header.ToUpperInvariant(),
|
||||
Margin = new MarginPadding { Bottom = 10, Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS },
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Black),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
},
|
||||
FlowContent
|
||||
});
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
using System.Collections.Generic;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Input.Bindings;
|
||||
|
@ -86,7 +87,18 @@ private void load(OsuColour colours, GameHost host)
|
|||
// todo: remove caching of this and consume via editorBeatmap?
|
||||
dependencies.Cache(beatDivisor);
|
||||
|
||||
playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
|
||||
try
|
||||
{
|
||||
playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Could not load beatmap successfully!");
|
||||
// couldn't load, hard abort!
|
||||
this.Exit();
|
||||
return;
|
||||
}
|
||||
|
||||
AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap));
|
||||
|
||||
dependencies.CacheAs(editorBeatmap);
|
||||
|
|
|
@ -152,7 +152,7 @@ private class HeaderText : OsuSpriteText
|
|||
public HeaderText(string text)
|
||||
{
|
||||
Text = text.ToUpper();
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black);
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Ranking;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Play
|
||||
{
|
||||
|
@ -115,7 +113,5 @@ protected override void Dispose(bool isDisposing)
|
|||
|
||||
Exited = null;
|
||||
}
|
||||
|
||||
protected override Results CreateResults(ScoreInfo score) => new MatchResults(score);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Ranking.Types;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Types;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Ranking
|
||||
{
|
||||
public class MatchResults : Results
|
||||
{
|
||||
public MatchResults(ScoreInfo score)
|
||||
: base(score)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
|
||||
{
|
||||
new ScoreOverviewPageInfo(Score, Beatmap.Value),
|
||||
new LocalLeaderboardPageInfo(Score, Beatmap.Value),
|
||||
new RoomLeaderboardPageInfo(Score, Beatmap.Value),
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Ranking.Pages
|
||||
{
|
||||
public class RoomLeaderboardPage : ResultsPage
|
||||
{
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
private TextFlowContainer rankText;
|
||||
|
||||
[Resolved(typeof(Room), nameof(Room.Name))]
|
||||
private Bindable<string> name { get; set; }
|
||||
|
||||
public RoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
MatchLeaderboard leaderboard;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray6,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new BufferedContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BackgroundColour = colours.Gray6,
|
||||
Child = leaderboard = CreateLeaderboard()
|
||||
},
|
||||
rankText = new TextFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.5f,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Y = 50,
|
||||
TextAnchor = Anchor.TopCentre
|
||||
},
|
||||
};
|
||||
|
||||
leaderboard.Origin = Anchor.Centre;
|
||||
leaderboard.Anchor = Anchor.Centre;
|
||||
leaderboard.RelativeSizeAxes = Axes.Both;
|
||||
leaderboard.Height = 0.8f;
|
||||
leaderboard.Y = 55;
|
||||
leaderboard.ScoresLoaded = scoresLoaded;
|
||||
}
|
||||
|
||||
private void scoresLoaded(IEnumerable<APIUserScoreAggregate> scores)
|
||||
{
|
||||
void gray(SpriteText s) => s.Colour = colours.GrayC;
|
||||
|
||||
void white(SpriteText s)
|
||||
{
|
||||
s.Font = s.Font.With(size: s.Font.Size * 1.4f);
|
||||
s.Colour = colours.GrayF;
|
||||
}
|
||||
|
||||
rankText.AddText(name + "\n", white);
|
||||
rankText.AddText("You are placed ", gray);
|
||||
|
||||
int index = scores.IndexOf(new APIUserScoreAggregate { User = Score.User }, new FuncEqualityComparer<APIUserScoreAggregate>((s1, s2) => s1.User.Id.Equals(s2.User.Id)));
|
||||
|
||||
rankText.AddText($"#{index + 1} ", s =>
|
||||
{
|
||||
s.Font = s.Font.With(Typeface.Torus, weight: FontWeight.Bold);
|
||||
s.Colour = colours.YellowDark;
|
||||
});
|
||||
|
||||
rankText.AddText("in the room!", gray);
|
||||
}
|
||||
|
||||
protected virtual MatchLeaderboard CreateLeaderboard() => new ResultsMatchLeaderboard();
|
||||
|
||||
public class ResultsMatchLeaderboard : MatchLeaderboard
|
||||
{
|
||||
protected override bool FadeTop => true;
|
||||
|
||||
protected override LeaderboardScore CreateDrawableScore(APIUserScoreAggregate model, int index)
|
||||
=> new ResultsMatchLeaderboardScore(model, index);
|
||||
|
||||
protected override FillFlowContainer<LeaderboardScore> CreateScoreFlow()
|
||||
{
|
||||
var flow = base.CreateScoreFlow();
|
||||
flow.Padding = new MarginPadding
|
||||
{
|
||||
Top = LeaderboardScore.HEIGHT * 2,
|
||||
Bottom = LeaderboardScore.HEIGHT * 3,
|
||||
};
|
||||
return flow;
|
||||
}
|
||||
|
||||
private class ResultsMatchLeaderboardScore : MatchLeaderboardScore
|
||||
{
|
||||
public ResultsMatchLeaderboardScore(APIUserScoreAggregate score, int rank)
|
||||
: base(score, rank)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
// 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 osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Ranking.Pages;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Ranking.Types
|
||||
{
|
||||
public class RoomLeaderboardPageInfo : IResultPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public RoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public IconUsage Icon => FontAwesome.Solid.Users;
|
||||
|
||||
public string Name => "Room Leaderboard";
|
||||
|
||||
public virtual ResultsPage CreatePage() => new RoomLeaderboardPage(score, beatmap);
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ public BreakInfo()
|
|||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "current progress".ToUpperInvariant(),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Black, size: 15),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
|
|
|
@ -401,14 +401,18 @@ private void onCompletion()
|
|||
|
||||
protected virtual ScoreInfo CreateScore()
|
||||
{
|
||||
var score = DrawableRuleset.ReplayScore?.ScoreInfo ?? new ScoreInfo
|
||||
var score = new ScoreInfo
|
||||
{
|
||||
Beatmap = Beatmap.Value.BeatmapInfo,
|
||||
Ruleset = rulesetInfo,
|
||||
Mods = Mods.Value.ToArray(),
|
||||
User = api.LocalUser.Value,
|
||||
};
|
||||
|
||||
if (DrawableRuleset.ReplayScore != null)
|
||||
score.User = DrawableRuleset.ReplayScore.ScoreInfo?.User ?? new GuestUser();
|
||||
else
|
||||
score.User = api.LocalUser.Value;
|
||||
|
||||
ScoreProcessor.PopulateScore(score);
|
||||
|
||||
return score;
|
||||
|
@ -416,7 +420,7 @@ protected virtual ScoreInfo CreateScore()
|
|||
|
||||
protected override bool OnScroll(ScrollEvent e) => mouseWheelDisabled.Value && !GameplayClockContainer.IsPaused.Value;
|
||||
|
||||
protected virtual Results CreateResults(ScoreInfo score) => new SoloResults(score);
|
||||
protected virtual ResultsScreen CreateResults(ScoreInfo score) => new ResultsScreen(score);
|
||||
|
||||
#region Fail Logic
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Ranking.Types;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class SoloResults : Results
|
||||
{
|
||||
public SoloResults(ScoreInfo score)
|
||||
: base(score)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
|
||||
{
|
||||
new ScoreOverviewPageInfo(Score, Beatmap.Value),
|
||||
new LocalLeaderboardPageInfo(Score, Beatmap.Value)
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// The component that displays the player's accuracy on the results screen.
|
||||
/// </summary>
|
||||
public class AccuracyCircle : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// Duration for the transforms causing this component to appear.
|
||||
/// </summary>
|
||||
public const double APPEAR_DURATION = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Delay before the accuracy circle starts filling.
|
||||
/// </summary>
|
||||
public const double ACCURACY_TRANSFORM_DELAY = 450;
|
||||
|
||||
/// <summary>
|
||||
/// Duration for the accuracy circle fill.
|
||||
/// </summary>
|
||||
public const double ACCURACY_TRANSFORM_DURATION = 3000;
|
||||
|
||||
/// <summary>
|
||||
/// Delay after <see cref="ACCURACY_TRANSFORM_DURATION"/> for the rank text (A/B/C/D/S/SS) to appear.
|
||||
/// </summary>
|
||||
public const double TEXT_APPEAR_DELAY = ACCURACY_TRANSFORM_DURATION / 2;
|
||||
|
||||
/// <summary>
|
||||
/// Delay before the rank circles start filling.
|
||||
/// </summary>
|
||||
public const double RANK_CIRCLE_TRANSFORM_DELAY = 150;
|
||||
|
||||
/// <summary>
|
||||
/// Duration for the rank circle fills.
|
||||
/// </summary>
|
||||
public const double RANK_CIRCLE_TRANSFORM_DURATION = 800;
|
||||
|
||||
/// <summary>
|
||||
/// Relative width of the rank circles.
|
||||
/// </summary>
|
||||
public const float RANK_CIRCLE_RADIUS = 0.06f;
|
||||
|
||||
/// <summary>
|
||||
/// Relative width of the circle showing the accuracy.
|
||||
/// </summary>
|
||||
private const float accuracy_circle_radius = 0.2f;
|
||||
|
||||
/// <summary>
|
||||
/// SS is displayed as a 1% region, otherwise it would be invisible.
|
||||
/// </summary>
|
||||
private const double virtual_ss_percentage = 0.01;
|
||||
|
||||
/// <summary>
|
||||
/// The easing for the circle filling transforms.
|
||||
/// </summary>
|
||||
public static readonly Easing ACCURACY_TRANSFORM_EASING = Easing.OutPow10;
|
||||
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
private SmoothCircularProgress accuracyCircle;
|
||||
private SmoothCircularProgress innerMask;
|
||||
private Container<RankBadge> badges;
|
||||
private RankText rankText;
|
||||
|
||||
public AccuracyCircle(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
Name = "Background circle",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.Gray(47),
|
||||
Alpha = 0.5f,
|
||||
InnerRadius = accuracy_circle_radius + 0.01f, // Extends a little bit into the circle
|
||||
Current = { Value = 1 },
|
||||
},
|
||||
accuracyCircle = new SmoothCircularProgress
|
||||
{
|
||||
Name = "Accuracy circle",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#7CF6FF"), Color4Extensions.FromHex("#BAFFA9")),
|
||||
InnerRadius = accuracy_circle_radius,
|
||||
},
|
||||
new BufferedContainer
|
||||
{
|
||||
Name = "Graded circles",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.8f),
|
||||
Padding = new MarginPadding(2),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#BE0089"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 1 }
|
||||
},
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#0096A2"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 1 - virtual_ss_percentage }
|
||||
},
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#72C904"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 0.95f }
|
||||
},
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#D99D03"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 0.9f }
|
||||
},
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#EA7948"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 0.8f }
|
||||
},
|
||||
new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#FF5858"),
|
||||
InnerRadius = RANK_CIRCLE_RADIUS,
|
||||
Current = { Value = 0.7f }
|
||||
},
|
||||
new RankNotch(0),
|
||||
new RankNotch((float)(1 - virtual_ss_percentage)),
|
||||
new RankNotch(0.95f),
|
||||
new RankNotch(0.9f),
|
||||
new RankNotch(0.8f),
|
||||
new RankNotch(0.7f),
|
||||
new BufferedContainer
|
||||
{
|
||||
Name = "Graded circle mask",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(1),
|
||||
Blending = new BlendingParameters
|
||||
{
|
||||
Source = BlendingType.DstColor,
|
||||
Destination = BlendingType.OneMinusSrcAlpha,
|
||||
SourceAlpha = BlendingType.One,
|
||||
DestinationAlpha = BlendingType.SrcAlpha
|
||||
},
|
||||
Child = innerMask = new SmoothCircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
InnerRadius = RANK_CIRCLE_RADIUS - 0.01f,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
badges = new Container<RankBadge>
|
||||
{
|
||||
Name = "Rank badges",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Vertical = -15, Horizontal = -20 },
|
||||
Children = new[]
|
||||
{
|
||||
new RankBadge(1f, ScoreRank.X),
|
||||
new RankBadge(0.95f, ScoreRank.S),
|
||||
new RankBadge(0.9f, ScoreRank.A),
|
||||
new RankBadge(0.8f, ScoreRank.B),
|
||||
new RankBadge(0.7f, ScoreRank.C),
|
||||
}
|
||||
},
|
||||
rankText = new RankText(score.Rank)
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
this.ScaleTo(0).Then().ScaleTo(1, APPEAR_DURATION, Easing.OutQuint);
|
||||
|
||||
using (BeginDelayedSequence(RANK_CIRCLE_TRANSFORM_DELAY, true))
|
||||
innerMask.FillTo(1f, RANK_CIRCLE_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
|
||||
|
||||
using (BeginDelayedSequence(ACCURACY_TRANSFORM_DELAY, true))
|
||||
{
|
||||
double targetAccuracy = score.Rank == ScoreRank.X || score.Rank == ScoreRank.XH ? 1 : Math.Min(1 - virtual_ss_percentage, score.Accuracy);
|
||||
|
||||
accuracyCircle.FillTo(targetAccuracy, ACCURACY_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
|
||||
|
||||
foreach (var badge in badges)
|
||||
{
|
||||
if (badge.Accuracy > score.Accuracy)
|
||||
continue;
|
||||
|
||||
using (BeginDelayedSequence(inverseEasing(ACCURACY_TRANSFORM_EASING, Math.Min(1 - virtual_ss_percentage, badge.Accuracy) / targetAccuracy) * ACCURACY_TRANSFORM_DURATION, true))
|
||||
badge.Appear();
|
||||
}
|
||||
|
||||
using (BeginDelayedSequence(TEXT_APPEAR_DELAY, true))
|
||||
rankText.Appear();
|
||||
}
|
||||
}
|
||||
|
||||
private double inverseEasing(Easing easing, double targetValue)
|
||||
{
|
||||
double test = 0;
|
||||
double result = 0;
|
||||
int count = 2;
|
||||
|
||||
while (Math.Abs(result - targetValue) > 0.005)
|
||||
{
|
||||
int dir = Math.Sign(targetValue - result);
|
||||
|
||||
test += dir * 1.0 / count;
|
||||
result = Interpolation.ApplyEasing(easing, test);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return test;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a <see cref="DrawableRank"/> that is positioned around the <see cref="AccuracyCircle"/>.
|
||||
/// </summary>
|
||||
public class RankBadge : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// The accuracy value corresponding to the <see cref="ScoreRank"/> displayed by this badge.
|
||||
/// </summary>
|
||||
public readonly float Accuracy;
|
||||
|
||||
private readonly ScoreRank rank;
|
||||
|
||||
private Drawable rankContainer;
|
||||
private Drawable overlay;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RankBadge"/>.
|
||||
/// </summary>
|
||||
/// <param name="accuracy">The accuracy value corresponding to <paramref name="rank"/>.</param>
|
||||
/// <param name="rank">The <see cref="ScoreRank"/> to be displayed in this <see cref="RankBadge"/>.</param>
|
||||
public RankBadge(float accuracy, ScoreRank rank)
|
||||
{
|
||||
Accuracy = accuracy;
|
||||
this.rank = rank;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Alpha = 0;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = rankContainer = new Container
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(28, 14),
|
||||
Children = new[]
|
||||
{
|
||||
new DrawableRank(rank),
|
||||
overlay = new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Blending = BlendingParameters.Additive,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = OsuColour.ForRank(rank).Opacity(0.2f),
|
||||
Radius = 10,
|
||||
},
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows this <see cref="RankBadge"/>.
|
||||
/// </summary>
|
||||
public void Appear()
|
||||
{
|
||||
this.FadeIn(50);
|
||||
overlay.FadeIn().FadeOut(500, Easing.In);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// Starts at -90deg (top) and moves counter-clockwise by the accuracy
|
||||
rankContainer.Position = circlePosition(-MathF.PI / 2 - (1 - Accuracy) * MathF.PI * 2);
|
||||
}
|
||||
|
||||
private Vector2 circlePosition(float t)
|
||||
=> DrawSize / 2 + new Vector2(MathF.Cos(t), MathF.Sin(t)) * DrawSize / 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// A solid "notch" of the <see cref="AccuracyCircle"/> that appears at the ends of the rank circles to add separation.
|
||||
/// </summary>
|
||||
public class RankNotch : CompositeDrawable
|
||||
{
|
||||
private readonly float position;
|
||||
|
||||
public RankNotch(float position)
|
||||
{
|
||||
this.position = position;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Rotation = position * 360f,
|
||||
Child = new Box
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Height = AccuracyCircle.RANK_CIRCLE_RADIUS,
|
||||
Width = 1f,
|
||||
Colour = OsuColour.Gray(0.3f),
|
||||
EdgeSmoothness = new Vector2(1f)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// The text that appears in the middle of the <see cref="AccuracyCircle"/> displaying the user's rank.
|
||||
/// </summary>
|
||||
public class RankText : CompositeDrawable
|
||||
{
|
||||
private readonly ScoreRank rank;
|
||||
|
||||
private BufferedContainer flash;
|
||||
private BufferedContainer superFlash;
|
||||
private GlowingSpriteText rankText;
|
||||
|
||||
public RankText(ScoreRank rank)
|
||||
{
|
||||
this.rank = rank;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Alpha = 0;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
rankText = new GlowingSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
GlowColour = OsuColour.ForRank(rank),
|
||||
Spacing = new Vector2(-15, 0),
|
||||
Text = DrawableRank.GetRankName(rank),
|
||||
Font = OsuFont.Numeric.With(size: 76),
|
||||
UseFullGlyphHeight = false
|
||||
},
|
||||
superFlash = new BufferedContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
BlurSigma = new Vector2(85),
|
||||
Size = new Vector2(600),
|
||||
CacheDrawnFrameBuffer = true,
|
||||
Blending = BlendingParameters.Additive,
|
||||
Alpha = 0,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = Color4.White,
|
||||
Size = new Vector2(150),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
},
|
||||
},
|
||||
flash = new BufferedContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
BlurSigma = new Vector2(35),
|
||||
BypassAutoSizeAxes = Axes.Both,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CacheDrawnFrameBuffer = true,
|
||||
Blending = BlendingParameters.Additive,
|
||||
Alpha = 0,
|
||||
Size = new Vector2(2f), // increase buffer size to allow for scale
|
||||
Scale = new Vector2(1.8f),
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Spacing = new Vector2(-15, 0),
|
||||
Text = DrawableRank.GetRankName(rank),
|
||||
Font = OsuFont.Numeric.With(size: 76),
|
||||
UseFullGlyphHeight = false,
|
||||
Shadow = false
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public void Appear()
|
||||
{
|
||||
this.FadeIn();
|
||||
|
||||
if (rank < ScoreRank.A)
|
||||
{
|
||||
this
|
||||
.MoveToOffset(new Vector2(0, -20))
|
||||
.MoveToOffset(new Vector2(0, 20), 200, Easing.OutBounce);
|
||||
|
||||
if (rank <= ScoreRank.D)
|
||||
{
|
||||
this.Delay(700)
|
||||
.RotateTo(5, 150, Easing.In)
|
||||
.MoveToOffset(new Vector2(0, 3), 150, Easing.In);
|
||||
}
|
||||
|
||||
this.FadeInFromZero(200, Easing.OutQuint);
|
||||
return;
|
||||
}
|
||||
|
||||
flash.Colour = OsuColour.ForRank(rank);
|
||||
flash.FadeIn().Then().FadeOut(1200, Easing.OutQuint);
|
||||
|
||||
if (rank >= ScoreRank.S)
|
||||
rankText.ScaleTo(1.05f).ScaleTo(1, 3000, Easing.OutQuint);
|
||||
|
||||
if (rank >= ScoreRank.X)
|
||||
{
|
||||
flash.FadeIn().Then().FadeOut(3000);
|
||||
superFlash.FadeIn().Then().FadeOut(800, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
// 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 osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a <see cref="CircularProgress"/> with smoothened edges.
|
||||
/// </summary>
|
||||
public class SmoothCircularProgress : CompositeDrawable
|
||||
{
|
||||
public Bindable<double> Current
|
||||
{
|
||||
get => progress.Current;
|
||||
set => progress.Current = value;
|
||||
}
|
||||
|
||||
public float InnerRadius
|
||||
{
|
||||
get => progress.InnerRadius;
|
||||
set
|
||||
{
|
||||
progress.InnerRadius = value;
|
||||
innerSmoothingContainer.Size = new Vector2(1 - value);
|
||||
smoothingWedge.Height = value / 2;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly CircularProgress progress;
|
||||
private readonly Container innerSmoothingContainer;
|
||||
private readonly Drawable smoothingWedge;
|
||||
|
||||
public SmoothCircularProgress()
|
||||
{
|
||||
Container smoothingWedgeContainer;
|
||||
|
||||
InternalChild = new BufferedContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
progress = new CircularProgress { RelativeSizeAxes = Axes.Both },
|
||||
smoothingWedgeContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = smoothingWedge = new Box
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 1f,
|
||||
EdgeSmoothness = new Vector2(2, 0),
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(-1),
|
||||
Child = new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BorderThickness = 2,
|
||||
Masking = true,
|
||||
BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f),
|
||||
Blending = new BlendingParameters
|
||||
{
|
||||
AlphaEquation = BlendingEquation.ReverseSubtract,
|
||||
},
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
}
|
||||
}
|
||||
},
|
||||
innerSmoothingContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = Vector2.Zero,
|
||||
Padding = new MarginPadding(-1),
|
||||
Child = new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BorderThickness = 2,
|
||||
BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f),
|
||||
Masking = true,
|
||||
Blending = new BlendingParameters
|
||||
{
|
||||
AlphaEquation = BlendingEquation.ReverseSubtract,
|
||||
},
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Current.BindValueChanged(c =>
|
||||
{
|
||||
smoothingWedgeContainer.Alpha = c.NewValue > 0 ? 1 : 0;
|
||||
smoothingWedgeContainer.Rotation = (float)(360 * c.NewValue);
|
||||
}, true);
|
||||
}
|
||||
|
||||
public TransformSequence<CircularProgress> FillTo(double newValue, double duration = 0, Easing easing = Easing.None)
|
||||
=> progress.FillTo(newValue, duration, easing);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osu.Game.Screens.Ranking.Expanded.Statistics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded
|
||||
{
|
||||
/// <summary>
|
||||
/// The content that appears in the middle section of the <see cref="ScorePanel"/>.
|
||||
/// </summary>
|
||||
public class ExpandedPanelMiddleContent : CompositeDrawable
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
private readonly List<StatisticDisplay> statisticDisplays = new List<StatisticDisplay>();
|
||||
private RollingCounter<long> scoreCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ExpandedPanelMiddleContent"/>.
|
||||
/// </summary>
|
||||
/// <param name="score">The score to display.</param>
|
||||
public ExpandedPanelMiddleContent(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Masking = true;
|
||||
|
||||
Padding = new MarginPadding { Vertical = 10, Horizontal = 10 };
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(Bindable<WorkingBeatmap> working)
|
||||
{
|
||||
var beatmap = working.Value.BeatmapInfo;
|
||||
var metadata = beatmap.Metadata;
|
||||
|
||||
var topStatistics = new List<StatisticDisplay>
|
||||
{
|
||||
new AccuracyStatistic(score.Accuracy),
|
||||
new ComboStatistic(score.MaxCombo, true),
|
||||
new CounterStatistic("pp", (int)(score.PP ?? 0)),
|
||||
};
|
||||
|
||||
var bottomStatistics = new List<StatisticDisplay>();
|
||||
foreach (var stat in score.SortedStatistics)
|
||||
bottomStatistics.Add(new CounterStatistic(stat.Key.GetDescription(), stat.Value));
|
||||
|
||||
statisticDisplays.AddRange(topStatistics);
|
||||
statisticDisplays.AddRange(bottomStatistics);
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = new LocalisedString((metadata.Title, metadata.TitleUnicode)),
|
||||
Font = OsuFont.Torus.With(size: 20, weight: FontWeight.SemiBold),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = new LocalisedString((metadata.Artist, metadata.ArtistUnicode)),
|
||||
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold)
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Margin = new MarginPadding { Top = 40 },
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 230,
|
||||
Child = new AccuracyCircle(score)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fit,
|
||||
}
|
||||
},
|
||||
scoreCounter = new TotalScoreCounter
|
||||
{
|
||||
Margin = new MarginPadding { Top = 0, Bottom = 5 },
|
||||
Current = { Value = 0 },
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StarRatingDisplay(beatmap)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft
|
||||
},
|
||||
new ModDisplay
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
DisplayUnrankedText = false,
|
||||
ExpansionMode = ExpansionMode.AlwaysExpanded,
|
||||
Scale = new Vector2(0.5f),
|
||||
Current = { Value = score.Mods }
|
||||
}
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = beatmap.Version,
|
||||
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold),
|
||||
},
|
||||
new OsuTextFlowContainer(s => s.Font = OsuFont.Torus.With(size: 12))
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
}.With(t =>
|
||||
{
|
||||
t.AddText("mapped by ");
|
||||
t.AddText(score.UserString, s => s.Font = s.Font.With(weight: FontWeight.SemiBold));
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Content = new[] { topStatistics.Cast<Drawable>().ToArray() },
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
}
|
||||
},
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Content = new[] { bottomStatistics.Cast<Drawable>().ToArray() },
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
// Score counter value setting must be scheduled so it isn't transferred instantaneously
|
||||
ScheduleAfterChildren(() =>
|
||||
{
|
||||
using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DELAY, true))
|
||||
{
|
||||
scoreCounter.FadeIn();
|
||||
scoreCounter.Current.Value = score.TotalScore;
|
||||
|
||||
double delay = 0;
|
||||
|
||||
foreach (var stat in statisticDisplays)
|
||||
{
|
||||
using (BeginDelayedSequence(delay, true))
|
||||
stat.Appear();
|
||||
|
||||
delay += 200;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Users.Drawables;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded
|
||||
{
|
||||
/// <summary>
|
||||
/// The content that appears in the middle section of the <see cref="ScorePanel"/>.
|
||||
/// </summary>
|
||||
public class ExpandedPanelTopContent : CompositeDrawable
|
||||
{
|
||||
private readonly User user;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ExpandedPanelTopContent"/>.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="User"/> to display.</param>
|
||||
public ExpandedPanelTopContent(User user)
|
||||
{
|
||||
this.user = user;
|
||||
Anchor = Anchor.TopCentre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new UpdateableAvatar(user)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Size = new Vector2(80),
|
||||
CornerRadius = 20,
|
||||
CornerExponent = 2.5f,
|
||||
Masking = true,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = user.Username,
|
||||
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
// 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.Globalization;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded
|
||||
{
|
||||
/// <summary>
|
||||
/// A pill that displays the star rating of a <see cref="BeatmapInfo"/>.
|
||||
/// </summary>
|
||||
public class StarRatingDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="StarRatingDisplay"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The <see cref="BeatmapInfo"/> to display the star difficulty of.</param>
|
||||
public StarRatingDisplay(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
var starRatingParts = beatmap.StarDifficulty.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
||||
string wholePart = starRatingParts[0];
|
||||
string fractionPart = starRatingParts[1];
|
||||
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||
|
||||
ColourInfo backgroundColour = beatmap.DifficultyRating == DifficultyRating.ExpertPlus
|
||||
? ColourInfo.GradientVertical(Color4Extensions.FromHex("#C1C1C1"), Color4Extensions.FromHex("#595959"))
|
||||
: (ColourInfo)colours.ForDifficultyRating(beatmap.DifficultyRating);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = backgroundColour
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = 8, Vertical = 4 },
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(2, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Size = new Vector2(7),
|
||||
Icon = FontAwesome.Solid.Star,
|
||||
Colour = Color4.Black
|
||||
},
|
||||
new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
TextAnchor = Anchor.BottomLeft,
|
||||
}.With(t =>
|
||||
{
|
||||
t.AddText($"{wholePart}", s =>
|
||||
{
|
||||
s.Colour = Color4.Black;
|
||||
s.Font = s.Font.With(size: 14);
|
||||
s.UseFullGlyphHeight = false;
|
||||
});
|
||||
|
||||
t.AddText($"{separator}{fractionPart}", s =>
|
||||
{
|
||||
s.Colour = Color4.Black;
|
||||
s.Font = s.Font.With(size: 7);
|
||||
s.UseFullGlyphHeight = false;
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// 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 osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osu.Game.Utils;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="StatisticDisplay"/> to display the player's accuracy.
|
||||
/// </summary>
|
||||
public class AccuracyStatistic : StatisticDisplay
|
||||
{
|
||||
private readonly double accuracy;
|
||||
|
||||
private RollingCounter<double> counter;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="AccuracyStatistic"/>.
|
||||
/// </summary>
|
||||
/// <param name="accuracy">The accuracy to display.</param>
|
||||
public AccuracyStatistic(double accuracy)
|
||||
: base("accuracy")
|
||||
{
|
||||
this.accuracy = accuracy;
|
||||
}
|
||||
|
||||
public override void Appear()
|
||||
{
|
||||
base.Appear();
|
||||
counter.Current.Value = accuracy;
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => counter = new Counter();
|
||||
|
||||
private class Counter : RollingCounter<double>
|
||||
{
|
||||
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||
|
||||
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||
|
||||
public Counter()
|
||||
{
|
||||
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true);
|
||||
DisplayedCountSpriteText.Spacing = new Vector2(-2, 0);
|
||||
}
|
||||
|
||||
protected override string FormatCount(double count) => count.FormatAccuracy();
|
||||
|
||||
public override void Increment(double amount)
|
||||
=> Current.Value += amount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// 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 osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="StatisticDisplay"/> to display the player's combo.
|
||||
/// </summary>
|
||||
public class ComboStatistic : CounterStatistic
|
||||
{
|
||||
private readonly bool isPerfect;
|
||||
|
||||
private Drawable perfectText;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ComboStatistic"/>.
|
||||
/// </summary>
|
||||
/// <param name="combo">The combo to be displayed.</param>
|
||||
/// <param name="isPerfect">Whether this is a perfect combo.</param>
|
||||
public ComboStatistic(int combo, bool isPerfect)
|
||||
: base("combo", combo)
|
||||
{
|
||||
this.isPerfect = isPerfect;
|
||||
}
|
||||
|
||||
public override void Appear()
|
||||
{
|
||||
base.Appear();
|
||||
|
||||
if (isPerfect)
|
||||
{
|
||||
using (BeginDelayedSequence(AccuracyCircle.ACCURACY_TRANSFORM_DURATION / 2, true))
|
||||
perfectText.FadeIn(50);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Children = new[]
|
||||
{
|
||||
base.CreateContent().With(d =>
|
||||
{
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
}),
|
||||
perfectText = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Text = "PERFECT",
|
||||
Font = OsuFont.Torus.With(size: 11, weight: FontWeight.SemiBold),
|
||||
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#66FFCC"), Color4Extensions.FromHex("#FF9AD7")),
|
||||
Alpha = 0,
|
||||
UseFullGlyphHeight = false,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// 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 osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="StatisticDisplay"/> to display general numeric values.
|
||||
/// </summary>
|
||||
public class CounterStatistic : StatisticDisplay
|
||||
{
|
||||
private readonly int count;
|
||||
|
||||
private RollingCounter<int> counter;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CounterStatistic"/>.
|
||||
/// </summary>
|
||||
/// <param name="header">The name of the statistic.</param>
|
||||
/// <param name="count">The value to display.</param>
|
||||
public CounterStatistic(string header, int count)
|
||||
: base(header)
|
||||
{
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public override void Appear()
|
||||
{
|
||||
base.Appear();
|
||||
counter.Current.Value = count;
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => counter = new Counter();
|
||||
|
||||
private class Counter : RollingCounter<int>
|
||||
{
|
||||
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||
|
||||
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||
|
||||
public Counter()
|
||||
{
|
||||
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 20, fixedWidth: true);
|
||||
DisplayedCountSpriteText.Spacing = new Vector2(-2, 0);
|
||||
}
|
||||
|
||||
public override void Increment(int amount)
|
||||
=> Current.Value += amount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
||||
{
|
||||
/// <summary>
|
||||
/// A statistic from the score to be displayed in the <see cref="ExpandedPanelMiddleContent"/>.
|
||||
/// </summary>
|
||||
public abstract class StatisticDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly string header;
|
||||
|
||||
private Drawable content;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="StatisticDisplay"/>.
|
||||
/// </summary>
|
||||
/// <param name="header">The name of the statistic.</param>
|
||||
protected StatisticDisplay(string header)
|
||||
{
|
||||
this.header = header;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new[]
|
||||
{
|
||||
new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 12,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#222")
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
|
||||
Text = header.ToUpperInvariant(),
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
content = CreateContent().With(d =>
|
||||
{
|
||||
d.Anchor = Anchor.TopCentre;
|
||||
d.Origin = Anchor.TopCentre;
|
||||
d.Alpha = 0;
|
||||
d.AlwaysPresent = true;
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the statistic value.
|
||||
/// </summary>
|
||||
public virtual void Appear() => content.FadeIn(100);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the content for this <see cref="StatisticDisplay"/>.
|
||||
/// </summary>
|
||||
protected abstract Drawable CreateContent();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// 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 osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Ranking.Expanded.Accuracy;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Expanded
|
||||
{
|
||||
/// <summary>
|
||||
/// A counter for the player's total score to be displayed in the <see cref="ExpandedPanelMiddleContent"/>.
|
||||
/// </summary>
|
||||
public class TotalScoreCounter : RollingCounter<long>
|
||||
{
|
||||
protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION;
|
||||
|
||||
protected override Easing RollingEasing => AccuracyCircle.ACCURACY_TRANSFORM_EASING;
|
||||
|
||||
public TotalScoreCounter()
|
||||
{
|
||||
// Todo: AutoSize X removed here due to https://github.com/ppy/osu-framework/issues/3369
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
DisplayedCountSpriteText.Anchor = Anchor.TopCentre;
|
||||
DisplayedCountSpriteText.Origin = Anchor.TopCentre;
|
||||
|
||||
DisplayedCountSpriteText.Font = OsuFont.Torus.With(size: 60, weight: FontWeight.Light, fixedWidth: true);
|
||||
DisplayedCountSpriteText.Spacing = new Vector2(-5, 0);
|
||||
}
|
||||
|
||||
protected override string FormatCount(long count) => count.ToString("N0");
|
||||
|
||||
public override void Increment(long amount)
|
||||
=> Current.Value += amount;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class LocalLeaderboardPage : ResultsPage
|
||||
{
|
||||
public LocalLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap = null)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray6,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new BeatmapLeaderboard
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Beatmap = Beatmap.BeatmapInfo ?? Score.Beatmap,
|
||||
Scale = new Vector2(0.7f)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,428 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
{
|
||||
public class ScoreResultsPage : ResultsPage
|
||||
{
|
||||
private Container scoreContainer;
|
||||
private ScoreCounter scoreCounter;
|
||||
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
public ScoreResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
: base(score, beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
private FillFlowContainer<DrawableScoreStatistic> statisticsContainer;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
const float user_header_height = 120;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = user_header_height },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.White,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DelayedLoadWrapper(new UserHeader(Score.User)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
})
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = user_header_height,
|
||||
},
|
||||
new UpdateableRank(Score.Rank)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Size = new Vector2(150, 60),
|
||||
Margin = new MarginPadding(20),
|
||||
},
|
||||
scoreContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 60,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SongProgressGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.5f,
|
||||
Objects = Beatmap.Beatmap.HitObjects,
|
||||
},
|
||||
scoreCounter = new SlowScoreCounter(6)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = colours.PinkDarker,
|
||||
Y = 10,
|
||||
TextSize = 56,
|
||||
},
|
||||
}
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = colours.PinkDarker,
|
||||
Shadow = false,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
Text = "total score",
|
||||
Margin = new MarginPadding { Bottom = 15 },
|
||||
},
|
||||
new BeatmapDetails(Beatmap.BeatmapInfo)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Margin = new MarginPadding { Bottom = 10 },
|
||||
},
|
||||
new DateTimeDisplay(Score.Date.LocalDateTime)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(0.75f, 1),
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Margin = new MarginPadding { Top = 10, Bottom = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = ColourInfo.GradientHorizontal(
|
||||
colours.GrayC.Opacity(0),
|
||||
colours.GrayC.Opacity(0.9f)),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.5f, 1),
|
||||
},
|
||||
new Box
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = ColourInfo.GradientHorizontal(
|
||||
colours.GrayC.Opacity(0.9f),
|
||||
colours.GrayC.Opacity(0)),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.5f, 1),
|
||||
},
|
||||
}
|
||||
},
|
||||
statisticsContainer = new FillFlowContainer<DrawableScoreStatistic>
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint
|
||||
},
|
||||
},
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Margin = new MarginPadding { Bottom = 10 },
|
||||
Spacing = new Vector2(5),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ReplayDownloadButton(score),
|
||||
new RetryButton()
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
statisticsContainer.ChildrenEnumerable = Score.SortedStatistics.Select(s => new DrawableScoreStatistic(s));
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
scoreCounter.Increment(Score.TotalScore);
|
||||
|
||||
int delay = 0;
|
||||
|
||||
foreach (var s in statisticsContainer.Children)
|
||||
{
|
||||
s.FadeOut()
|
||||
.Then(delay += 200)
|
||||
.FadeIn(300 + delay, Easing.Out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
scoreCounter.Scale = new Vector2(Math.Min(1f, (scoreContainer.DrawWidth - 20) / scoreCounter.DrawWidth));
|
||||
}
|
||||
|
||||
private class DrawableScoreStatistic : Container
|
||||
{
|
||||
private readonly KeyValuePair<HitResult, int> statistic;
|
||||
|
||||
public DrawableScoreStatistic(KeyValuePair<HitResult, int> statistic)
|
||||
{
|
||||
this.statistic = statistic;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Margin = new MarginPadding { Left = 5, Right = 5 };
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = statistic.Value.ToString().PadLeft(4, '0'),
|
||||
Colour = colours.Gray7,
|
||||
Font = OsuFont.GetFont(size: 30),
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = statistic.Key.GetDescription(),
|
||||
Colour = colours.Gray7,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
Y = 26,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class DateTimeDisplay : Container
|
||||
{
|
||||
private readonly DateTime date;
|
||||
|
||||
public DateTimeDisplay(DateTime date)
|
||||
{
|
||||
this.date = date;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Gray6,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Horizontal = 10, Vertical = 5 },
|
||||
Spacing = new Vector2(10),
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = date.ToShortDateString(),
|
||||
Colour = Color4.White,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = date.ToShortTimeString(),
|
||||
Colour = Color4.White,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class BeatmapDetails : Container
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
private readonly OsuSpriteText title;
|
||||
private readonly OsuSpriteText artist;
|
||||
private readonly OsuSpriteText versionMapper;
|
||||
|
||||
public BeatmapDetails(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
title = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Shadow = false,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 24, italics: true),
|
||||
},
|
||||
artist = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Shadow = false,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 20, italics: true),
|
||||
},
|
||||
versionMapper = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Shadow = false,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
title.Colour = artist.Colour = colours.BlueDarker;
|
||||
versionMapper.Colour = colours.Gray8;
|
||||
|
||||
var creator = beatmap.Metadata.Author?.Username;
|
||||
|
||||
if (!string.IsNullOrEmpty(creator))
|
||||
{
|
||||
versionMapper.Text = $"mapped by {creator}";
|
||||
|
||||
if (!string.IsNullOrEmpty(beatmap.Version))
|
||||
versionMapper.Text = $"{beatmap.Version} - " + versionMapper.Text;
|
||||
}
|
||||
|
||||
title.Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title));
|
||||
artist.Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist));
|
||||
}
|
||||
}
|
||||
|
||||
[LongRunningLoad]
|
||||
private class UserHeader : Container
|
||||
{
|
||||
private readonly User user;
|
||||
private readonly Sprite cover;
|
||||
|
||||
public UserHeader(User user)
|
||||
{
|
||||
this.user = user;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
cover = new Sprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fill,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Text = user.Username,
|
||||
Font = OsuFont.GetFont(size: 30, weight: FontWeight.Regular, italics: true),
|
||||
Padding = new MarginPadding { Bottom = 10 },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LargeTextureStore textures)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(user.CoverUrl))
|
||||
cover.Texture = textures.Get(user.CoverUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private class SlowScoreCounter : ScoreCounter
|
||||
{
|
||||
protected override double RollingDuration => 3000;
|
||||
|
||||
protected override Easing RollingEasing => Easing.OutPow10;
|
||||
|
||||
public SlowScoreCounter(uint leading = 0)
|
||||
: base(leading)
|
||||
{
|
||||
DisplayedCountSpriteText.Shadow = false;
|
||||
DisplayedCountSpriteText.Font = DisplayedCountSpriteText.Font.With(Typeface.Venera, weight: FontWeight.Light);
|
||||
UseCommaSeparator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,11 @@
|
|||
// 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 osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public interface IResultPageInfo
|
||||
public enum PanelState
|
||||
{
|
||||
IconUsage Icon { get; }
|
||||
|
||||
string Name { get; }
|
||||
|
||||
ResultsPage CreatePage();
|
||||
Expanded,
|
||||
Contracted
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ReplayDownloadButton : DownloadTrackingComposite<ScoreInfo, ScoreManager>
|
||||
{
|
|
@ -1,97 +0,0 @@
|
|||
// 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 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.Effects;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeButton : TabItem<IResultPageInfo>, IHasTooltip
|
||||
{
|
||||
private readonly IconUsage icon;
|
||||
private Color4 activeColour;
|
||||
private Color4 inactiveColour;
|
||||
private CircularContainer colouredPart;
|
||||
|
||||
public ResultModeButton(IResultPageInfo mode)
|
||||
: base(mode)
|
||||
{
|
||||
icon = mode.Icon;
|
||||
TooltipText = mode.Name;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Size = new Vector2(50);
|
||||
|
||||
Masking = true;
|
||||
|
||||
CornerRadius = 25;
|
||||
CornerExponent = 2;
|
||||
|
||||
activeColour = colours.PinkDarker;
|
||||
inactiveColour = OsuColour.Gray(0.8f);
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.4f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 5,
|
||||
};
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.White,
|
||||
},
|
||||
colouredPart = new CircularContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.8f),
|
||||
BorderThickness = 4,
|
||||
BorderColour = Color4.White,
|
||||
Colour = inactiveColour,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
AlwaysPresent = true, //for border rendering
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Transparent,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Shadow = false,
|
||||
Colour = OsuColour.Gray(0.95f),
|
||||
Icon = icon,
|
||||
Size = new Vector2(20),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, Easing.OutQuint);
|
||||
|
||||
protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint);
|
||||
|
||||
public string TooltipText { get; }
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// 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 osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultModeTabControl : TabControl<IResultPageInfo>
|
||||
{
|
||||
public ResultModeTabControl()
|
||||
{
|
||||
TabContainer.Anchor = Anchor.BottomCentre;
|
||||
TabContainer.Origin = Anchor.BottomCentre;
|
||||
TabContainer.Spacing = new Vector2(15);
|
||||
|
||||
TabContainer.Masking = false;
|
||||
TabContainer.Padding = new MarginPadding(5);
|
||||
}
|
||||
|
||||
protected override Dropdown<IResultPageInfo> CreateDropdown() => null;
|
||||
|
||||
protected override TabItem<IResultPageInfo> CreateTabItem(IResultPageInfo value) => new ResultModeButton(value)
|
||||
{
|
||||
Anchor = TabContainer.Anchor,
|
||||
Origin = TabContainer.Origin
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public abstract class Results : OsuScreen
|
||||
{
|
||||
protected const float BACKGROUND_BLUR = 20;
|
||||
|
||||
private Container circleOuterBackground;
|
||||
private Container circleOuter;
|
||||
private Container circleInner;
|
||||
|
||||
private ParallaxContainer backgroundParallax;
|
||||
|
||||
private ResultModeTabControl modeChangeButtons;
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private Player player { get; set; }
|
||||
|
||||
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
||||
|
||||
protected readonly ScoreInfo Score;
|
||||
|
||||
private Container currentPage;
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
|
||||
|
||||
private const float overscan = 1.3f;
|
||||
|
||||
private const float circle_outer_scale = 0.96f;
|
||||
|
||||
protected Results(ScoreInfo score)
|
||||
{
|
||||
Score = score;
|
||||
}
|
||||
|
||||
private const float transition_time = 800;
|
||||
|
||||
private IEnumerable<Drawable> allCircles => new Drawable[] { circleOuterBackground, circleInner, circleOuter };
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
((BackgroundScreenBeatmap)Background).BlurAmount.Value = BACKGROUND_BLUR;
|
||||
Background.ScaleTo(1.1f, transition_time, Easing.OutQuint);
|
||||
|
||||
allCircles.ForEach(c =>
|
||||
{
|
||||
c.FadeOut();
|
||||
c.ScaleTo(0);
|
||||
});
|
||||
|
||||
backgroundParallax.FadeOut();
|
||||
modeChangeButtons.FadeOut();
|
||||
currentPage?.FadeOut();
|
||||
|
||||
circleOuterBackground
|
||||
.FadeIn(transition_time, Easing.OutQuint)
|
||||
.ScaleTo(1, transition_time, Easing.OutQuint);
|
||||
|
||||
using (BeginDelayedSequence(transition_time * 0.25f, true))
|
||||
{
|
||||
circleOuter
|
||||
.FadeIn(transition_time, Easing.OutQuint)
|
||||
.ScaleTo(1, transition_time, Easing.OutQuint);
|
||||
|
||||
using (BeginDelayedSequence(transition_time * 0.3f, true))
|
||||
{
|
||||
backgroundParallax.FadeIn(transition_time, Easing.OutQuint);
|
||||
|
||||
circleInner
|
||||
.FadeIn(transition_time, Easing.OutQuint)
|
||||
.ScaleTo(1, transition_time, Easing.OutQuint);
|
||||
|
||||
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
||||
{
|
||||
modeChangeButtons.FadeIn(transition_time, Easing.OutQuint);
|
||||
currentPage?.FadeIn(transition_time, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnExiting(IScreen next)
|
||||
{
|
||||
allCircles.ForEach(c => c.ScaleTo(0, transition_time, Easing.OutSine));
|
||||
|
||||
Background.ScaleTo(1f, transition_time / 4, Easing.OutQuint);
|
||||
|
||||
this.FadeOut(transition_time / 4);
|
||||
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
InternalChild = new AspectContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Height = overscan,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
circleOuterBackground = new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Alpha = 0.2f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
}
|
||||
}
|
||||
},
|
||||
circleOuter = new CircularContainer
|
||||
{
|
||||
Size = new Vector2(circle_outer_scale),
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.4f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 15,
|
||||
},
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.White,
|
||||
},
|
||||
backgroundParallax = new ParallaxContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ParallaxAmount = 0.01f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Sprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.2f,
|
||||
Texture = Beatmap.Value.Background,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill
|
||||
}
|
||||
}
|
||||
},
|
||||
modeChangeButtons = new ResultModeTabControl
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 50,
|
||||
Margin = new MarginPadding { Bottom = 110 },
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Text = $"{Score.MaxCombo}x",
|
||||
RelativePositionAxes = Axes.X,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 40),
|
||||
X = 0.1f,
|
||||
Colour = colours.BlueDarker,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "max combo",
|
||||
Font = OsuFont.GetFont(size: 20),
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = 0.1f,
|
||||
Colour = colours.Gray6,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Text = Score.DisplayAccuracy,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 40),
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = 0.9f,
|
||||
Colour = colours.BlueDarker,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "accuracy",
|
||||
Font = OsuFont.GetFont(size: 20),
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = 0.9f,
|
||||
Colour = colours.Gray6,
|
||||
},
|
||||
}
|
||||
},
|
||||
circleInner = new CircularContainer
|
||||
{
|
||||
Size = new Vector2(0.6f),
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.4f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 15,
|
||||
},
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.White,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
AddInternal(new HotkeyRetryOverlay
|
||||
{
|
||||
Action = () =>
|
||||
{
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
player?.Restart();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
var pages = CreateResultPages();
|
||||
|
||||
foreach (var p in pages)
|
||||
modeChangeButtons.AddItem(p);
|
||||
|
||||
modeChangeButtons.Current.Value = pages.FirstOrDefault();
|
||||
|
||||
modeChangeButtons.Current.BindValueChanged(page =>
|
||||
{
|
||||
currentPage?.FadeOut();
|
||||
currentPage?.Expire();
|
||||
|
||||
currentPage = page.NewValue?.CreatePage();
|
||||
|
||||
if (currentPage != null)
|
||||
LoadComponentAsync(currentPage, circleInner.Add);
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<IResultPageInfo> CreateResultPages();
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public abstract class ResultsPage : Container
|
||||
{
|
||||
protected readonly ScoreInfo Score;
|
||||
protected readonly WorkingBeatmap Beatmap;
|
||||
private CircularContainer content;
|
||||
private Box fill;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
protected ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
Score = score;
|
||||
Beatmap = beatmap;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
fill.Delay(400).FadeInFromZero(600);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
fill = new Box
|
||||
{
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Gray6
|
||||
},
|
||||
new CircularContainer
|
||||
{
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = colours.GrayF.Opacity(0.8f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 1,
|
||||
},
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
BorderThickness = 20,
|
||||
BorderColour = Color4.White,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
},
|
||||
}
|
||||
},
|
||||
content = new CircularContainer
|
||||
{
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 15,
|
||||
},
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Size = new Vector2(0.88f),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Play;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ResultsScreen : OsuScreen
|
||||
{
|
||||
protected const float BACKGROUND_BLUR = 20;
|
||||
|
||||
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
||||
|
||||
// Temporary for now to stop dual transitions. Should respect the current toolbar mode, but there's no way to do so currently.
|
||||
public override bool HideOverlaysOnEnter => true;
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private Player player { get; set; }
|
||||
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
private Drawable bottomPanel;
|
||||
|
||||
public ResultsScreen(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new[]
|
||||
{
|
||||
new ResultsScrollContainer
|
||||
{
|
||||
Child = new ScorePanel(score)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
State = PanelState.Expanded
|
||||
},
|
||||
},
|
||||
bottomPanel = new Container
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = TwoLayerButton.SIZE_EXTENDED.Y,
|
||||
Alpha = 0,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex("#333")
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(5),
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ReplayDownloadButton(score) { Width = 300 },
|
||||
new RetryButton { Width = 300 },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
AddInternal(new HotkeyRetryOverlay
|
||||
{
|
||||
Action = () =>
|
||||
{
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
player?.Restart();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
((BackgroundScreenBeatmap)Background).BlurAmount.Value = BACKGROUND_BLUR;
|
||||
|
||||
Background.FadeTo(0.5f, 250);
|
||||
bottomPanel.FadeTo(1, 250);
|
||||
}
|
||||
|
||||
public override bool OnExiting(IScreen next)
|
||||
{
|
||||
Background.FadeTo(1, 250);
|
||||
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
||||
private class ResultsScrollContainer : OsuScrollContainer
|
||||
{
|
||||
private readonly Container content;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public ResultsScrollContainer()
|
||||
{
|
||||
base.Content.Add(content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X
|
||||
});
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
ScrollbarVisible = false;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
content.Height = DrawHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
using osu.Game.Screens.Play;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Pages
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class RetryButton : OsuAnimatedButton
|
||||
{
|
|
@ -0,0 +1,223 @@
|
|||
// 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 osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Expanded;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public class ScorePanel : CompositeDrawable, IStateful<PanelState>
|
||||
{
|
||||
/// <summary>
|
||||
/// Width of the panel when contracted.
|
||||
/// </summary>
|
||||
private const float contracted_width = 160;
|
||||
|
||||
/// <summary>
|
||||
/// Height of the panel when contracted.
|
||||
/// </summary>
|
||||
private const float contracted_height = 320;
|
||||
|
||||
/// <summary>
|
||||
/// Width of the panel when expanded.
|
||||
/// </summary>
|
||||
private const float expanded_width = 360;
|
||||
|
||||
/// <summary>
|
||||
/// Height of the panel when expanded.
|
||||
/// </summary>
|
||||
private const float expanded_height = 560;
|
||||
|
||||
/// <summary>
|
||||
/// Height of the top layer when the panel is expanded.
|
||||
/// </summary>
|
||||
private const float expanded_top_layer_height = 53;
|
||||
|
||||
/// <summary>
|
||||
/// Height of the top layer when the panel is contracted.
|
||||
/// </summary>
|
||||
private const float contracted_top_layer_height = 40;
|
||||
|
||||
/// <summary>
|
||||
/// Duration for the panel to resize into its expanded/contracted size.
|
||||
/// </summary>
|
||||
private const double resize_duration = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Delay after <see cref="resize_duration"/> before the top layer is expanded.
|
||||
/// </summary>
|
||||
private const double top_layer_expand_delay = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Duration for the top layer expansion.
|
||||
/// </summary>
|
||||
private const double top_layer_expand_duration = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Duration for the panel contents to fade in.
|
||||
/// </summary>
|
||||
private const double content_fade_duration = 50;
|
||||
|
||||
private static readonly ColourInfo expanded_top_layer_colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#444"), Color4Extensions.FromHex("#333"));
|
||||
private static readonly ColourInfo expanded_middle_layer_colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#555"), Color4Extensions.FromHex("#333"));
|
||||
private static readonly Color4 contracted_top_layer_colour = Color4Extensions.FromHex("#353535");
|
||||
private static readonly Color4 contracted_middle_layer_colour = Color4Extensions.FromHex("#444");
|
||||
|
||||
public event Action<PanelState> StateChanged;
|
||||
|
||||
private readonly ScoreInfo score;
|
||||
|
||||
private Container topLayerContainer;
|
||||
private Drawable topLayerBackground;
|
||||
private Container topLayerContentContainer;
|
||||
private Drawable topLayerContent;
|
||||
|
||||
private Container middleLayerContainer;
|
||||
private Drawable middleLayerBackground;
|
||||
private Container middleLayerContentContainer;
|
||||
private Drawable middleLayerContent;
|
||||
|
||||
public ScorePanel(ScoreInfo score)
|
||||
{
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
topLayerContainer = new Container
|
||||
{
|
||||
Name = "Top layer",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 120,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = 20,
|
||||
CornerExponent = 2.5f,
|
||||
Masking = true,
|
||||
Child = topLayerBackground = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
topLayerContentContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
},
|
||||
middleLayerContainer = new Container
|
||||
{
|
||||
Name = "Middle layer",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CornerRadius = 20,
|
||||
CornerExponent = 2.5f,
|
||||
Masking = true,
|
||||
Child = middleLayerBackground = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
middleLayerContentContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (state == PanelState.Expanded)
|
||||
{
|
||||
topLayerBackground.FadeColour(expanded_top_layer_colour);
|
||||
middleLayerBackground.FadeColour(expanded_middle_layer_colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
topLayerBackground.FadeColour(contracted_top_layer_colour);
|
||||
middleLayerBackground.FadeColour(contracted_middle_layer_colour);
|
||||
}
|
||||
|
||||
updateState();
|
||||
}
|
||||
|
||||
private PanelState state = PanelState.Contracted;
|
||||
|
||||
public PanelState State
|
||||
{
|
||||
get => state;
|
||||
set
|
||||
{
|
||||
if (state == value)
|
||||
return;
|
||||
|
||||
state = value;
|
||||
|
||||
if (LoadState >= LoadState.Ready)
|
||||
updateState();
|
||||
|
||||
StateChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
topLayerContainer.MoveToY(0, resize_duration, Easing.OutQuint);
|
||||
middleLayerContainer.MoveToY(0, resize_duration, Easing.OutQuint);
|
||||
|
||||
topLayerContent?.FadeOut(content_fade_duration).Expire();
|
||||
middleLayerContent?.FadeOut(content_fade_duration).Expire();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PanelState.Expanded:
|
||||
this.ResizeTo(new Vector2(expanded_width, expanded_height), resize_duration, Easing.OutQuint);
|
||||
|
||||
topLayerBackground.FadeColour(expanded_top_layer_colour, resize_duration, Easing.OutQuint);
|
||||
middleLayerBackground.FadeColour(expanded_middle_layer_colour, resize_duration, Easing.OutQuint);
|
||||
|
||||
topLayerContentContainer.Add(middleLayerContent = new ExpandedPanelTopContent(score.User).With(d => d.Alpha = 0));
|
||||
middleLayerContentContainer.Add(topLayerContent = new ExpandedPanelMiddleContent(score).With(d => d.Alpha = 0));
|
||||
break;
|
||||
|
||||
case PanelState.Contracted:
|
||||
this.ResizeTo(new Vector2(contracted_width, contracted_height), resize_duration, Easing.OutQuint);
|
||||
|
||||
topLayerBackground.FadeColour(contracted_top_layer_colour, resize_duration, Easing.OutQuint);
|
||||
middleLayerBackground.FadeColour(contracted_middle_layer_colour, resize_duration, Easing.OutQuint);
|
||||
break;
|
||||
}
|
||||
|
||||
using (BeginDelayedSequence(resize_duration + top_layer_expand_delay, true))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PanelState.Expanded:
|
||||
topLayerContainer.MoveToY(-expanded_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
|
||||
middleLayerContainer.MoveToY(expanded_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
|
||||
break;
|
||||
|
||||
case PanelState.Contracted:
|
||||
topLayerContainer.MoveToY(-contracted_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
|
||||
middleLayerContainer.MoveToY(contracted_top_layer_height / 2, top_layer_expand_duration, Easing.OutQuint);
|
||||
break;
|
||||
}
|
||||
|
||||
topLayerContent?.FadeIn(content_fade_duration);
|
||||
middleLayerContent?.FadeIn(content_fade_duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
// 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 osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class LocalLeaderboardPageInfo : IResultPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public LocalLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public IconUsage Icon => FontAwesome.Solid.User;
|
||||
|
||||
public string Name => @"Local Leaderboard";
|
||||
|
||||
public ResultsPage CreatePage() => new LocalLeaderboardPage(score, beatmap);
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// 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 osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking.Pages;
|
||||
|
||||
namespace osu.Game.Screens.Ranking.Types
|
||||
{
|
||||
public class ScoreOverviewPageInfo : IResultPageInfo
|
||||
{
|
||||
public IconUsage Icon => FontAwesome.Solid.Asterisk;
|
||||
|
||||
public string Name => "Overview";
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public ScoreOverviewPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public ResultsPage CreatePage()
|
||||
{
|
||||
return new ScoreResultsPage(score, beatmap);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
@ -311,20 +312,27 @@ private InfoLabel[] getInfoLabels()
|
|||
Content = getBPMRange(b),
|
||||
}));
|
||||
|
||||
IBeatmap playableBeatmap;
|
||||
|
||||
try
|
||||
{
|
||||
// Try to get the beatmap with the user's ruleset
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(ruleset, Array.Empty<Mod>());
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
// Can't be converted to the user's ruleset, so use the beatmap's own ruleset
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset, Array.Empty<Mod>());
|
||||
}
|
||||
IBeatmap playableBeatmap;
|
||||
|
||||
labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)));
|
||||
try
|
||||
{
|
||||
// Try to get the beatmap with the user's ruleset
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(ruleset, Array.Empty<Mod>());
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
// Can't be converted to the user's ruleset, so use the beatmap's own ruleset
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset, Array.Empty<Mod>());
|
||||
}
|
||||
|
||||
labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Could not load beatmap successfully!");
|
||||
}
|
||||
}
|
||||
|
||||
return labels.ToArray();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Users;
|
||||
using osuTK.Input;
|
||||
|
||||
|
@ -31,7 +32,7 @@ private void load(OsuColour colours)
|
|||
Edit();
|
||||
}, Key.Number4);
|
||||
|
||||
((PlayBeatmapDetailArea)BeatmapDetails).Leaderboard.ScoreSelected += score => this.Push(new SoloResults(score));
|
||||
((PlayBeatmapDetailArea)BeatmapDetails).Leaderboard.ScoreSelected += score => this.Push(new ResultsScreen(score));
|
||||
}
|
||||
|
||||
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea();
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.317.0" />
|
||||
<PackageReference Include="Sentry" Version="2.1.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.317.0" />
|
||||
</ItemGroup>
|
||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
|
@ -79,7 +79,7 @@
|
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.317.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
|
Loading…
Reference in New Issue