1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 15:02:55 +08:00

Merge branch 'master' into controls

This commit is contained in:
Huo Yaoyuan 2017-03-22 08:54:03 +08:00
commit e217c67bcf
53 changed files with 1390 additions and 181 deletions

@ -1 +1 @@
Subproject commit e6394035d443d4498b71e845e5763dd3faf98c7c Subproject commit 405537bd351954878ddc1d2ba53e5d0563528446

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Screens.Testing; using osu.Framework.Screens.Testing;
using osu.Game.Screens.Tournament; using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams; using osu.Game.Screens.Tournament.Teams;
using osu.Game.Users;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -24,57 +25,57 @@ namespace osu.Desktop.VisualTests.Tests
private class TestTeamList : ITeamList private class TestTeamList : ITeamList
{ {
public IEnumerable<Team> Teams { get; } = new[] public IEnumerable<Country> Teams { get; } = new[]
{ {
new Team new Country
{ {
FlagName = "GB", FlagName = "GB",
FullName = "United Kingdom", FullName = "United Kingdom",
Acronym = "UK" Acronym = "UK"
}, },
new Team new Country
{ {
FlagName = "FR", FlagName = "FR",
FullName = "France", FullName = "France",
Acronym = "FRA" Acronym = "FRA"
}, },
new Team new Country
{ {
FlagName = "CN", FlagName = "CN",
FullName = "China", FullName = "China",
Acronym = "CHN" Acronym = "CHN"
}, },
new Team new Country
{ {
FlagName = "AU", FlagName = "AU",
FullName = "Australia", FullName = "Australia",
Acronym = "AUS" Acronym = "AUS"
}, },
new Team new Country
{ {
FlagName = "JP", FlagName = "JP",
FullName = "Japan", FullName = "Japan",
Acronym = "JPN" Acronym = "JPN"
}, },
new Team new Country
{ {
FlagName = "RO", FlagName = "RO",
FullName = "Romania", FullName = "Romania",
Acronym = "ROM" Acronym = "ROM"
}, },
new Team new Country
{ {
FlagName = "IT", FlagName = "IT",
FullName = "Italy", FullName = "Italy",
Acronym = "PIZZA" Acronym = "PIZZA"
}, },
new Team new Country
{ {
FlagName = "VE", FlagName = "VE",
FullName = "Venezuela", FullName = "Venezuela",
Acronym = "VNZ" Acronym = "VNZ"
}, },
new Team new Country
{ {
FlagName = "US", FlagName = "US",
FullName = "United States of America", FullName = "United States of America",

View File

@ -0,0 +1,225 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Screens.Testing;
using osu.Game.Modes;
using osu.Game.Modes.Mods;
using osu.Game.Modes.Osu.Mods;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseLeaderboard : TestCase
{
public override string Description => @"From song select";
private Leaderboard leaderboard;
private void newScores()
{
var scores = new[]
{
new Score
{
Rank = ScoreRank.XH,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6602580,
Username = @"waaiiru",
Country = new Country
{
FullName = @"Spain",
FlagName = @"ES",
},
},
},
new Score
{
Rank = ScoreRank.X,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 4608074,
Username = @"Skycries",
Country = new Country
{
FullName = @"Brazil",
FlagName = @"BR",
},
},
},
new Score
{
Rank = ScoreRank.SH,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 1014222,
Username = @"eLy",
Country = new Country
{
FullName = @"Japan",
FlagName = @"JP",
},
},
},
new Score
{
Rank = ScoreRank.S,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 1541390,
Username = @"Toukai",
Country = new Country
{
FullName = @"Canada",
FlagName = @"CA",
},
},
},
new Score
{
Rank = ScoreRank.A,
Accuracy = 100,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2243452,
Username = @"Satoruu",
Country = new Country
{
FullName = @"Venezuela",
FlagName = @"VE",
},
},
},
new Score
{
Rank = ScoreRank.B,
Accuracy = 98.26,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2705430,
Username = @"Mooha",
Country = new Country
{
FullName = @"France",
FlagName = @"FR",
},
},
},
new Score
{
Rank = ScoreRank.C,
Accuracy = 96.54,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 7151382,
Username = @"Mayuri Hana",
Country = new Country
{
FullName = @"Thailand",
FlagName = @"TH",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 60.25,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 2051389,
Username = @"FunOrange",
Country = new Country
{
FullName = @"Canada",
FlagName = @"CA",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 51.40,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6169483,
Username = @"-Hebel-",
Country = new Country
{
FullName = @"Mexico",
FlagName = @"MX",
},
},
},
new Score
{
Rank = ScoreRank.F,
Accuracy = 42.22,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
User = new User
{
Id = 6702666,
Username = @"prhtnsm",
Country = new Country
{
FullName = @"Germany",
FlagName = @"DE",
},
},
},
};
leaderboard.Scores = scores;
}
public override void Reset()
{
base.Reset();
Add(leaderboard = new Leaderboard
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f),
});
AddButton(@"New Scores", newScores);
newScores();
}
}
}

View File

@ -204,6 +204,7 @@
<Compile Include="Tests\TestCaseModSelectOverlay.cs" /> <Compile Include="Tests\TestCaseModSelectOverlay.cs" />
<Compile Include="Tests\TestCaseDialogOverlay.cs" /> <Compile Include="Tests\TestCaseDialogOverlay.cs" />
<Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" /> <Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" />
<Compile Include="Tests\TestCaseLeaderboard.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />

View File

@ -215,6 +215,7 @@ namespace osu.Desktop.Overlays
Origin = Anchor.Centre, Origin = Anchor.Centre,
Icon = FontAwesome.fa_upload, Icon = FontAwesome.fa_upload,
Colour = Color4.White, Colour = Color4.White,
TextSize = 20
} }
}); });
} }

View File

@ -158,6 +158,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
if (!IsLoaded) return;
base.UpdateState(state); base.UpdateState(state);
ball.FadeIn(); ball.FadeIn();

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Modes.Taiko.Judgements
{
public enum TaikoHitResult
{
Good,
Great
}
}

View File

@ -7,5 +7,77 @@ namespace osu.Game.Modes.Taiko.Judgements
{ {
public class TaikoJudgementInfo : JudgementInfo public class TaikoJudgementInfo : JudgementInfo
{ {
/// <summary>
/// The maximum score value.
/// </summary>
public const TaikoHitResult MAX_HIT_RESULT = TaikoHitResult.Great;
/// <summary>
/// The score value.
/// </summary>
public TaikoHitResult TaikoResult;
/// <summary>
/// The score value for the combo portion of the score.
/// </summary>
public int ScoreValue => NumericResultForScore(TaikoResult);
/// <summary>
/// The score value for the accuracy portion of the score.
/// </summary>
public int AccuracyScoreValue => NumericResultForAccuracy(TaikoResult);
/// <summary>
/// The maximum score value for the combo portion of the score.
/// </summary>
public int MaxScoreValue => NumericResultForScore(MAX_HIT_RESULT);
/// <summary>
/// The maximum score value for the accuracy portion of the score.
/// </summary>
public int MaxAccuracyScoreValue => NumericResultForAccuracy(MAX_HIT_RESULT);
/// <summary>
/// Whether this Judgement has a secondary hit in the case of finishers.
/// </summary>
public bool SecondHit;
/// <summary>
/// Computes the numeric score value for the combo portion of the score.
/// For the accuracy portion of the score (including accuracy percentage), see <see cref="NumericResultForAccuracy(TaikoHitResult)"/>.
/// </summary>
/// <param name="result">The result to compute the score value for.</param>
/// <returns>The numeric score value.</returns>
protected virtual int NumericResultForScore(TaikoHitResult result)
{
switch (result)
{
default:
return 0;
case TaikoHitResult.Good:
return 100;
case TaikoHitResult.Great:
return 300;
}
}
/// <summary>
/// Computes the numeric score value for the accuracy portion of the score.
/// For the combo portion of the score, see <see cref="NumericResultForScore(TaikoHitResult)"/>.
/// </summary>
/// <param name="result">The result to compute the score value for.</param>
/// <returns>The numeric score value.</returns>
protected virtual int NumericResultForAccuracy(TaikoHitResult result)
{
switch (result)
{
default:
return 0;
case TaikoHitResult.Good:
return 150;
case TaikoHitResult.Great:
return 300;
}
}
} }
} }

View File

@ -50,6 +50,7 @@
<Compile Include="Beatmaps\TaikoBeatmapConverter.cs" /> <Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
<Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" /> <Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" />
<Compile Include="Judgements\TaikoJudgementInfo.cs" /> <Compile Include="Judgements\TaikoJudgementInfo.cs" />
<Compile Include="Judgements\TaikoHitResult.cs" />
<Compile Include="TaikoDifficultyCalculator.cs" /> <Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHit.cs" /> <Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
<Compile Include="Objects\TaikoHitObject.cs" /> <Compile Include="Objects\TaikoHitObject.cs" />

View File

@ -207,7 +207,8 @@ namespace osu.Game.Beatmaps.Formats
VelocityAdjustment = beatLength < 0 ? -beatLength / 100.0 : 1, VelocityAdjustment = beatLength < 0 ? -beatLength / 100.0 : 1,
TimingChange = split.Length <= 6 || split[6][0] == '1', TimingChange = split.Length <= 6 || split[6][0] == '1',
KiaiMode = (effectFlags & 1) > 0, KiaiMode = (effectFlags & 1) > 0,
OmitFirstBarLine = (effectFlags & 8) > 0 OmitFirstBarLine = (effectFlags & 8) > 0,
TimeSignature = (TimeSignatures)int.Parse(split[2])
}; };
} }

View File

@ -11,18 +11,12 @@ namespace osu.Game.Beatmaps.Timing
TimingChange = true, TimingChange = true,
}; };
public TimeSignatures TimeSignature;
public double Time; public double Time;
public double BeatLength; public double BeatLength;
public double VelocityAdjustment; public double VelocityAdjustment;
public bool TimingChange; public bool TimingChange;
public bool KiaiMode; public bool KiaiMode;
public bool OmitFirstBarLine; public bool OmitFirstBarLine;
}
internal enum TimeSignatures
{
SimpleQuadruple = 4,
SimpleTriple = 3
} }
} }

View File

@ -0,0 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Beatmaps.Timing
{
public enum TimeSignatures
{
SimpleQuadruple = 4,
SimpleTriple = 3
}
}

View File

@ -23,7 +23,8 @@ namespace osu.Game.Configuration
Set(OsuConfig.SavePassword, false); Set(OsuConfig.SavePassword, false);
Set(OsuConfig.SaveUsername, true); Set(OsuConfig.SaveUsername, true);
Set(OsuConfig.CursorSize, 1.0, 0.5f, 2); Set(OsuConfig.MenuCursorSize, 1.0, 0.5f, 2);
Set(OsuConfig.GameplayCursorSize, 1.0, 0.5f, 2);
Set(OsuConfig.DimLevel, 30, 0, 100); Set(OsuConfig.DimLevel, 30, 0, 100);
Set(OsuConfig.MouseDisableButtons, false); Set(OsuConfig.MouseDisableButtons, false);
@ -223,7 +224,8 @@ namespace osu.Game.Configuration
ComboFireHeight, ComboFireHeight,
ConfirmExit, ConfirmExit,
AutoSendNowPlaying, AutoSendNowPlaying,
CursorSize, MenuCursorSize,
GameplayCursorSize,
AutomaticCursorSizing, AutomaticCursorSizing,
DimLevel, DimLevel,
Display, Display,

View File

@ -54,7 +54,7 @@ namespace osu.Game.Graphics.Cursor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
cursorScale = config.GetBindable<double>(OsuConfig.CursorSize); cursorScale = config.GetBindable<double>(OsuConfig.GameplayCursorSize);
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -97,7 +97,7 @@ namespace osu.Game.Graphics.Cursor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) private void load(OsuConfigManager config, TextureStore textures, OsuColour colour)
{ {
cursorScale = config.GetBindable<double>(OsuConfig.CursorSize); cursorScale = config.GetBindable<double>(OsuConfig.MenuCursorSize);
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -1,11 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics namespace osu.Game.Graphics
{ {
public class TextAwesome : SpriteText public class TextAwesome : OsuSpriteText
{ {
//public override FontFace FontFace => (int)Icon < 0xf000 ? FontFace.OsuFont : FontFace.FontAwesome; //public override FontFace FontFace => (int)Icon < 0xf000 ? FontFace.OsuFont : FontFace.FontAwesome;

View File

@ -54,6 +54,7 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.CentreRight, Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight, Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 4 }, Margin = new MarginPadding { Right = 4 },
TextSize = 20
} }
}; };
} }

View File

@ -1,19 +1,63 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using Newtonsoft.Json;
using osu.Game.Users;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes.Mods;
namespace osu.Game.Modes namespace osu.Game.Modes
{ {
public class Score public class Score
{ {
[JsonProperty(@"rank")]
public ScoreRank Rank { get; set; }
[JsonProperty(@"score")]
public double TotalScore { get; set; } public double TotalScore { get; set; }
public double Accuracy { get; set; } public double Accuracy { get; set; }
public double Health { get; set; } public double Health { get; set; }
[JsonProperty(@"maxcombo")]
public int MaxCombo { get; set; } public int MaxCombo { get; set; }
public int Combo { get; set; } public int Combo { get; set; }
public Mod[] Mods { get; set; }
public User User { get; set; }
[JsonProperty(@"replay_data")]
public Replay Replay; public Replay Replay;
public BeatmapInfo Beatmap; public BeatmapInfo Beatmap;
[JsonProperty(@"score_id")]
public long OnlineScoreID;
[JsonProperty(@"username")]
public string Username;
[JsonProperty(@"user_id")]
public long UserID;
[JsonProperty(@"date")]
public DateTime Date;
// [JsonProperty(@"count50")] 0,
//[JsonProperty(@"count100")] 0,
//[JsonProperty(@"count300")] 100,
//[JsonProperty(@"countmiss")] 0,
//[JsonProperty(@"countkatu")] 0,
//[JsonProperty(@"countgeki")] 31,
//[JsonProperty(@"perfect")] true,
//[JsonProperty(@"enabled_mods")] [
// "DT",
// "FL",
// "HD",
// "HR"
//],
//[JsonProperty(@"rank")] "XH",
//[JsonProperty(@"pp")] 26.1816,
//[JsonProperty(@"replay")] true
} }
} }

View File

@ -0,0 +1,29 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
namespace osu.Game.Modes
{
public enum ScoreRank
{
[Description(@"F")]
F,
[Description(@"F")]
D,
[Description(@"C")]
C,
[Description(@"B")]
B,
[Description(@"A")]
A,
[Description(@"S")]
S,
[Description(@"SPlus")]
SH,
[Description(@"SS")]
X,
[Description(@"SSPlus")]
XH,
}
}

View File

@ -66,12 +66,14 @@ namespace osu.Game.Modes.UI
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Icon = FontAwesome.fa_osu_mod_bg, Icon = FontAwesome.fa_osu_mod_bg,
Shadow = true, Shadow = true,
TextSize = 20
}, },
modIcon = new TextAwesome modIcon = new TextAwesome
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Colour = OsuColour.Gray(84), Colour = OsuColour.Gray(84),
TextSize = 20
}, },
}; };

View File

@ -7,6 +7,7 @@ using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Objects.Drawables;
using OpenTK; using OpenTK;
using osu.Game.Modes.Judgements; using osu.Game.Modes.Judgements;
using osu.Framework.Allocation;
namespace osu.Game.Modes.UI namespace osu.Game.Modes.UI
{ {
@ -45,10 +46,16 @@ namespace osu.Game.Modes.UI
} }
}); });
Add(HitObjects = new HitObjectContainer<DrawableHitObject<TObject, TJudgement>> HitObjects = new HitObjectContainer<DrawableHitObject<TObject, TJudgement>>
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}); };
}
[BackgroundDependencyLoader]
private void load()
{
Add(HitObjects);
} }
/// <summary> /// <summary>

View File

@ -58,13 +58,20 @@ namespace osu.Game.Online.API
public event APISuccessHandler Success; public event APISuccessHandler Success;
public event APIFailureHandler Failure; public event APIFailureHandler Failure;
private bool cancelled;
private Action pendingFailure;
public void Perform(APIAccess api) public void Perform(APIAccess api)
{ {
this.api = api;
if (checkAndProcessFailure())
return;
if (startTime == null) if (startTime == null)
startTime = DateTime.Now.TotalMilliseconds(); startTime = DateTime.Now.TotalMilliseconds();
this.api = api;
if (remainingTime <= 0) if (remainingTime <= 0)
throw new TimeoutException(@"API request timeout hit"); throw new TimeoutException(@"API request timeout hit");
@ -72,18 +79,41 @@ namespace osu.Game.Online.API
WebRequest.RetryCount = 0; WebRequest.RetryCount = 0;
WebRequest.Headers[@"Authorization"] = $@"Bearer {api.AccessToken}"; WebRequest.Headers[@"Authorization"] = $@"Bearer {api.AccessToken}";
if (checkAndProcessFailure())
return;
if (!WebRequest.Aborted) //could have been aborted by a Cancel() call
WebRequest.BlockingPerform(); WebRequest.BlockingPerform();
if (checkAndProcessFailure())
return;
api.Scheduler.Add(delegate { Success?.Invoke(); }); api.Scheduler.Add(delegate { Success?.Invoke(); });
} }
public void Cancel() => Fail(new OperationCanceledException(@"Request cancelled"));
public void Fail(Exception e) public void Fail(Exception e)
{ {
cancelled = true;
WebRequest?.Abort(); WebRequest?.Abort();
api.Scheduler.Add(delegate
pendingFailure = () => Failure?.Invoke(e);
checkAndProcessFailure();
}
/// <summary>
/// Checked for cancellation or error. Also queues up the Failed event if we can.
/// </summary>
/// <returns>Whether we are in a failed or cancelled state.</returns>
private bool checkAndProcessFailure()
{ {
Failure?.Invoke(e); if (api == null || pendingFailure == null) return cancelled;
});
api.Scheduler.Add(pendingFailure);
pendingFailure = null;
return true;
} }
} }

View File

@ -0,0 +1,40 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Game.Database;
using osu.Game.Modes;
namespace osu.Game.Online.API.Requests
{
public class GetScoresRequest : APIRequest<GetScoresResponse>
{
private readonly BeatmapInfo beatmap;
public GetScoresRequest(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.AddParameter(@"c", beatmap.Hash);
req.AddParameter(@"f", beatmap.Path);
return req;
}
protected override string Target => @"beatmaps/scores";
}
public class GetScoresResponse
{
[JsonProperty(@"beatmap")]
public BeatmapInfo Beatmap;
[JsonProperty(@"scores")]
public IEnumerable<Score> Scores;
}
}

View File

@ -279,6 +279,7 @@ namespace osu.Game
//central game mode change logic. //central game mode change logic.
if (!currentScreen.ShowOverlays) if (!currentScreen.ShowOverlays)
{ {
options.State = Visibility.Hidden;
Toolbar.State = Visibility.Hidden; Toolbar.State = Visibility.Hidden;
musicController.State = Visibility.Hidden; musicController.State = Visibility.Hidden;
chat.State = Visibility.Hidden; chat.State = Visibility.Hidden;

View File

@ -169,6 +169,7 @@ namespace osu.Game.Overlays.Notifications
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Icon = FontAwesome.fa_times_circle, Icon = FontAwesome.fa_times_circle,
TextSize = 20
} }
}; };
} }

View File

@ -53,6 +53,7 @@ namespace osu.Game.Overlays.Notifications
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Icon = icon, Icon = icon,
TextSize = 20
} }
}); });

View File

@ -32,6 +32,7 @@ namespace osu.Game.Overlays.Options
{ {
Icon = Ruleset.GetRuleset(m).Icon, Icon = Ruleset.GetRuleset(m).Icon,
Colour = Color4.Gray, Colour = Color4.Gray,
TextSize = 20
}); });
Children = new Drawable[] Children = new Drawable[]

View File

@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using System;
namespace osu.Game.Overlays.Options.Sections.Graphics namespace osu.Game.Overlays.Options.Sections.Graphics
{ {
@ -12,9 +13,16 @@ namespace osu.Game.Overlays.Options.Sections.Graphics
{ {
protected override string Header => "Layout"; protected override string Header => "Layout";
private OptionSlider<int> letterboxPositionX;
private OptionSlider<int> letterboxPositionY;
private Bindable<bool> letterboxing;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(FrameworkConfigManager config) private void load(FrameworkConfigManager config)
{ {
letterboxing = config.GetBindable<bool>(FrameworkConfig.Letterboxing);
Children = new Drawable[] Children = new Drawable[]
{ {
new OptionLabel { Text = "Resolution: TODO dropdown" }, new OptionLabel { Text = "Resolution: TODO dropdown" },
@ -26,19 +34,36 @@ namespace osu.Game.Overlays.Options.Sections.Graphics
new OsuCheckbox new OsuCheckbox
{ {
LabelText = "Letterboxing", LabelText = "Letterboxing",
Bindable = config.GetBindable<bool>(FrameworkConfig.Letterboxing), Bindable = letterboxing,
}, },
new OptionSlider<int> letterboxPositionX = new OptionSlider<int>
{ {
LabelText = "Horizontal position", LabelText = "Horizontal position",
Bindable = (BindableInt)config.GetBindable<int>(FrameworkConfig.LetterboxPositionX) Bindable = (BindableInt)config.GetBindable<int>(FrameworkConfig.LetterboxPositionX)
}, },
new OptionSlider<int> letterboxPositionY = new OptionSlider<int>
{ {
LabelText = "Vertical position", LabelText = "Vertical position",
Bindable = (BindableInt)config.GetBindable<int>(FrameworkConfig.LetterboxPositionY) Bindable = (BindableInt)config.GetBindable<int>(FrameworkConfig.LetterboxPositionY)
}, },
}; };
letterboxing.ValueChanged += visibilityChanged;
letterboxing.TriggerChange();
}
private void visibilityChanged(object sender, EventArgs e)
{
if (letterboxing)
{
letterboxPositionX.Show();
letterboxPositionY.Show();
}
else
{
letterboxPositionX.Hide();
letterboxPositionY.Hide();
}
} }
} }
} }

View File

@ -61,8 +61,13 @@ namespace osu.Game.Overlays.Options.Sections
}, },
new OptionSlider<double> new OptionSlider<double>
{ {
LabelText = "Cursor size", LabelText = "Menu cursor size",
Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.CursorSize) Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.MenuCursorSize)
},
new OptionSlider<double>
{
LabelText = "Gameplay cursor size",
Bindable = (BindableDouble)config.GetBindable<double>(OsuConfig.GameplayCursorSize)
}, },
new OsuCheckbox new OsuCheckbox
{ {

View File

@ -87,6 +87,7 @@ namespace osu.Game.Overlays.Options
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
TextSize = 20
}, },
} }
}, },

View File

@ -98,6 +98,7 @@ namespace osu.Game.Overlays.Toolbar
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
TextSize = 20
}, },
DrawableText = new OsuSpriteText DrawableText = new OsuSpriteText
{ {

View File

@ -1,14 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Diagnostics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Users;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -26,7 +24,20 @@ namespace osu.Game.Overlays.Toolbar
Add(new OpaqueBackground { Depth = 1 }); Add(new OpaqueBackground { Depth = 1 });
Flow.Add(avatar = new Avatar()); Flow.Add(avatar = new Avatar
{
Masking = true,
Size = new Vector2(32),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
CornerRadius = 4,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 4,
Colour = Color4.Black.Opacity(0.1f),
}
});
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -49,86 +60,5 @@ namespace osu.Game.Overlays.Toolbar
break; break;
} }
} }
public class Avatar : Container
{
public Drawable Sprite;
private int userId;
private OsuGame game;
private Texture guestTexture;
public Avatar()
{
Size = new Vector2(32);
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
CornerRadius = Size.X / 8;
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 4,
Colour = Color4.Black.Opacity(0.1f),
};
Masking = true;
}
[BackgroundDependencyLoader]
private void load(OsuGame game, TextureStore textures)
{
this.game = game;
guestTexture = textures.Get(@"Online/avatar-guest");
}
public int UserId
{
get { return userId; }
set
{
if (userId == value)
return;
userId = value;
var newSprite = userId > 1 ? new OnlineSprite($@"https://a.ppy.sh/{userId}") : new Sprite { Texture = guestTexture };
newSprite.FillMode = FillMode.Fit;
newSprite.LoadAsync(game, s =>
{
Sprite?.FadeOut();
Sprite?.Expire();
Sprite = s;
Add(s);
//todo: fix this... clock dependencies are a pain
if (s.Clock != null)
s.FadeInFromZero(200);
});
}
}
public class OnlineSprite : Sprite
{
private readonly string url;
public OnlineSprite(string url)
{
Debug.Assert(url != null);
this.url = url;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(url);
}
}
}
} }
} }

View File

@ -71,6 +71,8 @@ namespace osu.Game.Screens
BackgroundScreen bg = CreateBackground(); BackgroundScreen bg = CreateBackground();
OnBeatmapChanged(Beatmap);
if (lastOsu?.Background != null) if (lastOsu?.Background != null)
{ {
if (bg == null || lastOsu.Background.Equals(bg)) if (bg == null || lastOsu.Background.Equals(bg))

View File

@ -237,14 +237,16 @@ namespace osu.Game.Screens.Select
Icon = FontAwesome.fa_square, Icon = FontAwesome.fa_square,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Colour = new Color4(68, 17, 136, 255), Colour = new Color4(68, 17, 136, 255),
Rotation = 45 Rotation = 45,
TextSize = 20
}, },
new TextAwesome new TextAwesome
{ {
Icon = statistic.Icon, Icon = statistic.Icon,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Colour = new Color4(255, 221, 85, 255), Colour = new Color4(255, 221, 85, 255),
Scale = new Vector2(0.8f) Scale = new Vector2(0.8f),
TextSize = 20
}, },
new OsuSpriteText new OsuSpriteText
{ {

View File

@ -0,0 +1,39 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Modes;
using osu.Framework.Extensions;
namespace osu.Game.Screens.Select.Leaderboards
{
public class DrawableRank : Container
{
private Sprite sprite;
public ScoreRank Rank { get; private set; }
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
sprite.Texture = textures.Get($@"Badges/ScoreRanks/{Rank.GetDescription()}");
}
public DrawableRank(ScoreRank rank)
{
Rank = rank;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}

View File

@ -0,0 +1,111 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Modes;
using System;
namespace osu.Game.Screens.Select.Leaderboards
{
public class Leaderboard : Container
{
private ScrollContainer scrollContainer;
private FillFlowContainer<LeaderboardScore> scrollFlow;
private IEnumerable<Score> scores;
public IEnumerable<Score> Scores
{
get { return scores; }
set
{
scores = value;
int i = 150;
if (scores == null)
{
foreach (var c in scrollFlow.Children)
c.FadeOut(i += 10);
foreach (var c in scrollFlow.Children)
c.LifetimeEnd = Time.Current + i;
return;
}
scrollFlow.Clear();
i = 0;
foreach (var s in scores)
{
var ls = new LeaderboardScore(s, 1 + i)
{
AlwaysPresent = true,
State = Visibility.Hidden,
};
scrollFlow.Add(ls);
ls.Delay(i++ * 50, true);
ls.Show();
}
scrollContainer.ScrollTo(0f, false);
}
}
public Leaderboard()
{
Children = new Drawable[]
{
scrollContainer = new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollDraggerVisible = false,
Children = new Drawable[]
{
scrollFlow = new FillFlowContainer<LeaderboardScore>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 5f),
Padding = new MarginPadding(5),
},
},
},
};
}
protected override void Update()
{
base.Update();
var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight;
if (!scrollContainer.IsScrolledToEnd())
fadeStart -= LeaderboardScore.HEIGHT;
foreach (var c in scrollFlow.Children)
{
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
var bottomY = topY + LeaderboardScore.HEIGHT;
if (bottomY < fadeStart)
c.Colour = Color4.White;
else if (topY > fadeStart + LeaderboardScore.HEIGHT)
c.Colour = Color4.Transparent;
else
{
c.ColourInfo = ColourInfo.GradientVertical(
Color4.White.Opacity(Math.Min(1 - (topY - fadeStart) / LeaderboardScore.HEIGHT, 1)),
Color4.White.Opacity(Math.Min(1 - (bottomY - fadeStart) / LeaderboardScore.HEIGHT, 1)));
}
}
}
}
}

View File

@ -0,0 +1,386 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Modes.Mods;
using osu.Game.Users;
using osu.Framework;
namespace osu.Game.Screens.Select.Leaderboards
{
public class LeaderboardScore : Container, IStateful<Visibility>
{
public static readonly float HEIGHT = 60;
public readonly int RankPosition;
public readonly Score Score;
private const float corner_radius = 5;
private const float edge_margin = 5;
private const float background_alpha = 0.25f;
private const float rank_width = 30;
private Box background;
private Container content, avatar;
private DrawableRank scoreRank;
private OsuSpriteText nameLabel;
private GlowingSpriteText scoreLabel;
private ScoreComponentLabel maxCombo, accuracy;
private Container flagBadgeContainer;
private FillFlowContainer<ScoreModIcon> modsContainer;
private Visibility state;
public Visibility State
{
get { return state; }
set
{
state = value;
switch (state)
{
case Visibility.Hidden:
foreach (var d in new Drawable[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
d.FadeOut();
Alpha = 0;
content.MoveToY(75);
avatar.MoveToX(75);
nameLabel.MoveToX(150);
break;
case Visibility.Visible:
FadeIn(200);
content.MoveToY(0, 800, EasingTypes.OutQuint);
Delay(100, true);
avatar.FadeIn(300, EasingTypes.OutQuint);
nameLabel.FadeIn(350, EasingTypes.OutQuint);
avatar.MoveToX(0, 300, EasingTypes.OutQuint);
nameLabel.MoveToX(0, 350, EasingTypes.OutQuint);
Delay(250, true);
scoreLabel.FadeIn(200);
scoreRank.FadeIn(200);
Delay(50, true);
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
for (int i = 0; i < drawables.Length; i++)
{
drawables[i].FadeIn(100 + i * 50);
}
break;
}
}
}
public LeaderboardScore(Score score, int rank)
{
Score = score;
RankPosition = rank;
RelativeSizeAxes = Axes.X;
Height = HEIGHT;
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Y,
Width = rank_width,
Children = new[]
{
new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = @"Exo2.0-MediumItalic",
TextSize = 22,
Text = RankPosition.ToString(),
},
},
},
content = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = rank_width, },
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = corner_radius,
Masking = true,
Children = new[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = background_alpha,
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(edge_margin),
Children = new Drawable[]
{
avatar = new Avatar
{
Size = new Vector2(HEIGHT - edge_margin * 2, HEIGHT - edge_margin * 2),
CornerRadius = corner_radius,
Masking = true,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Radius = 1,
Colour = Color4.Black.Opacity(0.2f),
},
UserId = Score.User?.Id ?? Score.UserID,
},
new Container
{
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Position = new Vector2(HEIGHT - edge_margin, 0f),
Children = new Drawable[]
{
nameLabel = new OsuSpriteText
{
Text = Score.User?.Username ?? Score.Username,
Font = @"Exo2.0-BoldItalic",
TextSize = 23,
},
new FillFlowContainer
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10f, 0f),
Children = new Drawable[]
{
flagBadgeContainer = new Container
{
Size = new Vector2(87f, 20f),
Masking = true,
Children = new Drawable[]
{
new DrawableFlag(Score.User?.Country?.FlagName ?? "__")
{
Width = 30,
RelativeSizeAxes = Axes.Y,
},
},
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10f, 0f),
Margin = new MarginPadding { Left = edge_margin, },
Children = new Drawable[]
{
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()),
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:0}" : @"{0:0.00}", Score.Accuracy)),
},
},
},
},
},
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
new Container
{
Size = new Vector2(40f, 20f),
Children = new[]
{
scoreRank = new DrawableRank(Score.Rank)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(40f),
},
},
},
},
},
modsContainer = new FillFlowContainer<ScoreModIcon>
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
},
},
},
},
},
};
if (Score.Mods != null)
{
foreach (Mod mod in Score.Mods)
{
// TODO: Get actual mod colours
modsContainer.Add(new ScoreModIcon(mod.Icon, OsuColour.FromHex(@"ffcc22")));
}
}
}
public void ToggleVisibility() => State = State == Visibility.Visible ? Visibility.Hidden : Visibility.Visible;
public override void Hide() => State = Visibility.Hidden;
public override void Show() => State = Visibility.Visible;
protected override bool OnHover(Framework.Input.InputState state)
{
background.FadeTo(0.5f, 300, EasingTypes.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(Framework.Input.InputState state)
{
background.FadeTo(background_alpha, 200, EasingTypes.OutQuint);
base.OnHoverLost(state);
}
private class GlowingSpriteText : Container
{
public GlowingSpriteText(string text, string font, int textSize, Color4 textColour, Color4 glowColour)
{
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
new BufferedContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BlurSigma = new Vector2(4),
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Size = new Vector2(3f),
Children = new[]
{
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = font,
TextSize = textSize,
FixedWidth = true,
Text = text,
Colour = glowColour,
Shadow = false,
},
},
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = font,
FixedWidth = true,
TextSize = textSize,
Text = text,
Colour = textColour,
Shadow = false,
},
};
}
}
private class ScoreModIcon : Container
{
public ScoreModIcon(FontAwesome icon, Color4 colour)
{
AutoSizeAxes = Axes.Both;
Children = new[]
{
new TextAwesome
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Icon = FontAwesome.fa_osu_mod_bg,
Colour = colour,
Shadow = true,
TextSize = 30,
UseFullGlyphHeight = false,
},
new TextAwesome
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Icon = icon,
Colour = OsuColour.Gray(84),
TextSize = 18,
Position = new Vector2(0f, 2f),
UseFullGlyphHeight = false,
},
};
}
}
private class ScoreComponentLabel : Container
{
public ScoreComponentLabel(FontAwesome icon, string value)
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
Size = new Vector2(60f, 20f);
Padding = new MarginPadding { Top = 10f, };
Children = new Drawable[]
{
new TextAwesome
{
Origin = Anchor.Centre,
Icon = FontAwesome.fa_square,
Colour = OsuColour.FromHex(@"3087ac"),
Rotation = 45,
Shadow = true,
},
new TextAwesome
{
Origin = Anchor.Centre,
Icon = icon,
Colour = OsuColour.FromHex(@"a4edff"),
Scale = new Vector2(0.8f),
},
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
{
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 15, },
},
};
}
}
}
}

View File

@ -8,9 +8,11 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Select.Leaderboards;
namespace osu.Game.Screens.Select namespace osu.Game.Screens.Select
{ {
@ -18,6 +20,7 @@ namespace osu.Game.Screens.Select
{ {
private OsuScreen player; private OsuScreen player;
private ModSelectOverlay modSelect; private ModSelectOverlay modSelect;
private Leaderboard leaderboard;
public PlaySongSelect() public PlaySongSelect()
{ {
@ -28,6 +31,11 @@ namespace osu.Game.Screens.Select
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Margin = new MarginPadding { Bottom = 50 } Margin = new MarginPadding { Bottom = 50 }
}); });
LeftContent.Add(leaderboard = new Leaderboard
{
RelativeSizeAxes = Axes.Both,
});
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -44,12 +52,29 @@ namespace osu.Game.Screens.Select
}, Key.Number3); }, Key.Number3);
} }
private GetScoresRequest getScoresRequest;
protected override void OnBeatmapChanged(WorkingBeatmap beatmap) protected override void OnBeatmapChanged(WorkingBeatmap beatmap)
{ {
beatmap?.Mods.BindTo(modSelect.SelectedMods); beatmap?.Mods.BindTo(modSelect.SelectedMods);
updateLeaderboard(beatmap);
base.OnBeatmapChanged(beatmap); base.OnBeatmapChanged(beatmap);
} }
private void updateLeaderboard(WorkingBeatmap beatmap)
{
leaderboard.Scores = null;
getScoresRequest?.Cancel();
if (beatmap?.BeatmapInfo == null) return;
getScoresRequest = new GetScoresRequest(beatmap.BeatmapInfo);
getScoresRequest.Success += r => leaderboard.Scores = r.Scores;
Game.API.Queue(getScoresRequest);
}
protected override void OnResuming(Screen last) protected override void OnResuming(Screen last)
{ {
player = null; player = null;

View File

@ -26,6 +26,7 @@ namespace osu.Game.Screens.Select
Origin = Anchor.CentreRight, Origin = Anchor.CentreRight,
Anchor = Anchor.CentreRight, Anchor = Anchor.CentreRight,
Margin = new MarginPadding { Right = 10 }, Margin = new MarginPadding { Right = 10 },
TextSize = 20
} }
}); });

View File

@ -39,9 +39,15 @@ namespace osu.Game.Screens.Select
private TrackManager trackManager; private TrackManager trackManager;
private DialogOverlay dialogOverlay; private DialogOverlay dialogOverlay;
private static readonly Vector2 wedged_container_size = new Vector2(0.5f, 225);
private static readonly Vector2 wedged_container_size = new Vector2(0.5f, 245);
private const float left_area_padding = 20;
private BeatmapInfoWedge beatmapInfoWedge; private BeatmapInfoWedge beatmapInfoWedge;
protected Container LeftContent;
private static readonly Vector2 background_blur = new Vector2(20); private static readonly Vector2 background_blur = new Vector2(20);
private CancellationTokenSource initialAddSetsTask; private CancellationTokenSource initialAddSetsTask;
@ -81,6 +87,20 @@ namespace osu.Game.Screens.Select
} }
} }
}); });
Add(LeftContent = new Container
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(wedged_container_size.X, 1),
Padding = new MarginPadding
{
Bottom = 50,
Top = wedged_container_size.Y + left_area_padding,
Left = left_area_padding,
Right = left_area_padding * 2,
}
});
Add(carousel = new BeatmapCarousel Add(carousel = new BeatmapCarousel
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
@ -104,8 +124,8 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Margin = new MarginPadding Margin = new MarginPadding
{ {
Top = 20, Top = left_area_padding,
Right = 20, Right = left_area_padding,
}, },
X = -50, X = -50,
}); });

View File

@ -21,6 +21,7 @@ using osu.Game.Screens.Tournament.Components;
using osu.Game.Screens.Tournament.Teams; using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -36,7 +37,7 @@ namespace osu.Game.Screens.Tournament
private GroupContainer groupsContainer; private GroupContainer groupsContainer;
private OsuSpriteText fullTeamNameText; private OsuSpriteText fullTeamNameText;
private List<Team> allTeams = new List<Team>(); private List<Country> allTeams = new List<Country>();
private DrawingsConfigManager drawingsConfig; private DrawingsConfigManager drawingsConfig;
@ -160,7 +161,7 @@ namespace osu.Game.Screens.Tournament
Text = "Control Panel", Text = "Control Panel",
TextSize = 22f, TextSize = 22f,
Font = "Exo2.0-Boldd" Font = "Exo2.0-Bold"
}, },
new FillFlowContainer new FillFlowContainer
{ {
@ -238,7 +239,7 @@ namespace osu.Game.Screens.Tournament
reset(true); reset(true);
} }
private void onTeamSelected(Team team) private void onTeamSelected(Country team)
{ {
groupsContainer.AddTeam(team); groupsContainer.AddTeam(team);
@ -275,7 +276,7 @@ namespace osu.Game.Screens.Tournament
teamsContainer.ClearTeams(); teamsContainer.ClearTeams();
allTeams.Clear(); allTeams.Clear();
foreach (Team t in TeamList.Teams) foreach (Country t in TeamList.Teams)
{ {
if (groupsContainer.ContainsTeam(t.FullName)) if (groupsContainer.ContainsTeam(t.FullName))
continue; continue;
@ -311,7 +312,7 @@ namespace osu.Game.Screens.Tournament
if (line.ToUpper().StartsWith("GROUP")) if (line.ToUpper().StartsWith("GROUP"))
continue; continue;
Team teamToAdd = allTeams.FirstOrDefault(t => t.FullName == line); Country teamToAdd = allTeams.FirstOrDefault(t => t.FullName == line);
if (teamToAdd == null) if (teamToAdd == null)
continue; continue;

View File

@ -11,9 +11,9 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Tournament
}; };
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
GroupTeam gt = new GroupTeam(team); GroupTeam gt = new GroupTeam(team);
@ -91,7 +91,7 @@ namespace osu.Game.Screens.Tournament
return allTeams.Any(t => t.Team.FullName == fullName); return allTeams.Any(t => t.Team.FullName == fullName);
} }
public bool RemoveTeam(Team team) public bool RemoveTeam(Country team)
{ {
allTeams.RemoveAll(gt => gt.Team == team); allTeams.RemoveAll(gt => gt.Team == team);
@ -122,12 +122,12 @@ namespace osu.Game.Screens.Tournament
private class GroupTeam : Container private class GroupTeam : Container
{ {
public Team Team; public Country Team;
private FillFlowContainer innerContainer; private FillFlowContainer innerContainer;
private Sprite flagSprite; private Sprite flagSprite;
public GroupTeam(Team team) public GroupTeam(Country team)
{ {
Team = team; Team = team;

View File

@ -7,8 +7,8 @@ using System.Linq;
using System.Text; using System.Text;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
@ -64,7 +64,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
if (groups[currentGroup].TeamsCount == maxTeams) if (groups[currentGroup].TeamsCount == maxTeams)
return; return;

View File

@ -13,18 +13,18 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.Transforms;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Screens.Tournament.Teams;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament namespace osu.Game.Screens.Tournament
{ {
public class ScrollingTeamContainer : Container public class ScrollingTeamContainer : Container
{ {
public event Action OnScrollStarted; public event Action OnScrollStarted;
public event Action<Team> OnSelected; public event Action<Country> OnSelected;
private readonly List<Team> availableTeams = new List<Team>(); private readonly List<Country> availableTeams = new List<Country>();
private Container tracker; private Container tracker;
@ -158,7 +158,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public void AddTeam(Team team) public void AddTeam(Country team)
{ {
if (availableTeams.Contains(team)) if (availableTeams.Contains(team))
return; return;
@ -169,12 +169,12 @@ namespace osu.Game.Screens.Tournament
scrollState = ScrollState.Idle; scrollState = ScrollState.Idle;
} }
public void AddTeams(IEnumerable<Team> teams) public void AddTeams(IEnumerable<Country> teams)
{ {
if (teams == null) if (teams == null)
return; return;
foreach (Team t in teams) foreach (Country t in teams)
AddTeam(t); AddTeam(t);
} }
@ -185,7 +185,7 @@ namespace osu.Game.Screens.Tournament
scrollState = ScrollState.Idle; scrollState = ScrollState.Idle;
} }
public void RemoveTeam(Team team) public void RemoveTeam(Country team)
{ {
availableTeams.Remove(team); availableTeams.Remove(team);
@ -270,7 +270,7 @@ namespace osu.Game.Screens.Tournament
private void addFlags() private void addFlags()
{ {
foreach (Team t in availableTeams) foreach (Country t in availableTeams)
{ {
Add(new ScrollingTeam(t) Add(new ScrollingTeam(t)
{ {
@ -326,7 +326,7 @@ namespace osu.Game.Screens.Tournament
public const float WIDTH = 58; public const float WIDTH = 58;
public const float HEIGHT = 41; public const float HEIGHT = 41;
public Team Team; public Country Team;
private Sprite flagSprite; private Sprite flagSprite;
private Box outline; private Box outline;
@ -346,7 +346,7 @@ namespace osu.Game.Screens.Tournament
} }
} }
public ScrollingTeam(Team team) public ScrollingTeam(Country team)
{ {
Team = team; Team = team;

View File

@ -2,11 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament.Teams namespace osu.Game.Screens.Tournament.Teams
{ {
public interface ITeamList public interface ITeamList
{ {
IEnumerable<Team> Teams { get; } IEnumerable<Country> Teams { get; }
} }
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Users;
namespace osu.Game.Screens.Tournament.Teams namespace osu.Game.Screens.Tournament.Teams
{ {
@ -20,11 +21,11 @@ namespace osu.Game.Screens.Tournament.Teams
this.storage = storage; this.storage = storage;
} }
public IEnumerable<Team> Teams public IEnumerable<Country> Teams
{ {
get get
{ {
var teams = new List<Team>(); var teams = new List<Country>();
try try
{ {
@ -52,7 +53,7 @@ namespace osu.Game.Screens.Tournament.Teams
string acronym = split.Length >= 3 ? split[2].Trim() : teamName; string acronym = split.Length >= 3 ? split[2].Trim() : teamName;
acronym = acronym.Substring(0, Math.Min(3, acronym.Length)); acronym = acronym.Substring(0, Math.Min(3, acronym.Length));
teams.Add(new Team teams.Add(new Country
{ {
FlagName = flagName, FlagName = flagName,
FullName = teamName, FullName = teamName,

View File

@ -1,23 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Tournament.Teams
{
public class Team
{
/// <summary>
/// The name of this team.
/// </summary>
public string FullName;
/// <summary>
/// Short acronym which appears in the group boxes post-selection.
/// </summary>
public string Acronym;
/// <summary>
/// Two-letter flag acronym (ISO 3166 standard)
/// </summary>
public string FlagName;
}
}

114
osu.Game/Users/Avatar.cs Normal file
View File

@ -0,0 +1,114 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Diagnostics;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Users
{
public class Avatar : Container
{
public Drawable Sprite;
private long userId;
private OsuGameBase game;
private Texture guestTexture;
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuGameBase game, TextureStore textures)
{
this.game = game;
guestTexture = textures.Get(@"Online/avatar-guest");
}
public long UserId
{
get { return userId; }
set
{
if (userId == value)
return;
userId = value;
invalidateSprite();
}
}
private Task loadTask;
private void invalidateSprite()
{
Sprite?.FadeOut(100);
Sprite?.Expire();
Sprite = null;
}
private void updateSprite()
{
if (loadTask != null || Sprite != null) return;
var newSprite = userId > 1 ? new OnlineSprite($@"https://a.ppy.sh/{userId}", guestTexture) : new Sprite { Texture = guestTexture };
newSprite.FillMode = FillMode.Fill;
loadTask = newSprite.LoadAsync(game, s =>
{
Sprite = s;
Add(Sprite);
Sprite.FadeInFromZero(200);
loadTask = null;
});
}
private double timeVisible;
private bool shouldUpdate => Sprite != null || timeVisible > 500;
protected override void Update()
{
base.Update();
if (!shouldUpdate)
{
//Special optimisation to not start loading until we are within bounds of our closest ScrollContainer parent.
ScrollContainer scroll = null;
IContainer cursor = this;
while (scroll == null && (cursor = cursor.Parent) != null)
scroll = cursor as ScrollContainer;
if (scroll?.ScreenSpaceDrawQuad.Intersects(ScreenSpaceDrawQuad) ?? true)
timeVisible += Time.Elapsed;
else
timeVisible = 0;
}
if (shouldUpdate)
updateSprite();
}
public class OnlineSprite : Sprite
{
private readonly string url;
private readonly Texture fallbackTexture;
public OnlineSprite(string url, Texture fallbackTexture = null)
{
Debug.Assert(url != null);
this.url = url;
this.fallbackTexture = fallbackTexture;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(url) ?? fallbackTexture;
}
}
}
}

67
osu.Game/Users/Country.cs Normal file
View File

@ -0,0 +1,67 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Users
{
public class Country
{
/// <summary>
/// The name of this country.
/// </summary>
public string FullName;
/// <summary>
/// Short acronym which appears in the group boxes post-selection.
/// </summary>
public string Acronym;
/// <summary>
/// Two-letter flag acronym (ISO 3166 standard)
/// </summary>
public string FlagName;
}
public class DrawableFlag : Container
{
private Sprite sprite;
private TextureStore textures;
private string flagName;
public string FlagName
{
get { return flagName; }
set
{
if (value == flagName) return;
flagName = value;
sprite.Texture = textures.Get($@"Flags/{flagName}");
}
}
[BackgroundDependencyLoader]
private void load(TextureStore ts)
{
textures = ts;
sprite.Texture = textures.Get($@"Flags/{flagName}");
}
public DrawableFlag(string name = @"__")
{
flagName = name;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}

10
osu.Game/Users/Team.cs Normal file
View File

@ -0,0 +1,10 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Users
{
public class Team
{
public string Name;
}
}

View File

@ -7,5 +7,7 @@ namespace osu.Game.Users
{ {
public int Id; public int Id;
public string Username; public string Username;
public Country Country;
public Team Team;
} }
} }

View File

@ -76,6 +76,7 @@
<Compile Include="Beatmaps\IBeatmapCoverter.cs" /> <Compile Include="Beatmaps\IBeatmapCoverter.cs" />
<Compile Include="Beatmaps\IBeatmapProcessor.cs" /> <Compile Include="Beatmaps\IBeatmapProcessor.cs" />
<Compile Include="Beatmaps\Legacy\LegacyBeatmap.cs" /> <Compile Include="Beatmaps\Legacy\LegacyBeatmap.cs" />
<Compile Include="Beatmaps\Timing\TimeSignatures.cs" />
<Compile Include="Beatmaps\Timing\TimingInfo.cs" /> <Compile Include="Beatmaps\Timing\TimingInfo.cs" />
<Compile Include="Database\ScoreDatabase.cs" /> <Compile Include="Database\ScoreDatabase.cs" />
<Compile Include="Graphics\Backgrounds\Triangles.cs" /> <Compile Include="Graphics\Backgrounds\Triangles.cs" />
@ -129,6 +130,7 @@
<Compile Include="Modes\UI\StandardHealthDisplay.cs" /> <Compile Include="Modes\UI\StandardHealthDisplay.cs" />
<Compile Include="Modes\UI\StandardHudOverlay.cs" /> <Compile Include="Modes\UI\StandardHudOverlay.cs" />
<Compile Include="Online\API\IOnlineComponent.cs" /> <Compile Include="Online\API\IOnlineComponent.cs" />
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
<Compile Include="Online\API\Requests\GetUserRequest.cs" /> <Compile Include="Online\API\Requests\GetUserRequest.cs" />
<Compile Include="Overlays\DragBar.cs" /> <Compile Include="Overlays\DragBar.cs" />
<Compile Include="Overlays\LoginOverlay.cs" /> <Compile Include="Overlays\LoginOverlay.cs" />
@ -241,7 +243,7 @@
<Compile Include="Online\API\OAuth.cs" /> <Compile Include="Online\API\OAuth.cs" />
<Compile Include="Online\API\OAuthToken.cs" /> <Compile Include="Online\API\OAuthToken.cs" />
<Compile Include="Online\API\Requests\GetMessagesRequest.cs" /> <Compile Include="Online\API\Requests\GetMessagesRequest.cs" />
<Compile Include="Online\API\Requests\ListChannels.cs" /> <Compile Include="Online\API\Requests\ListChannelsRequest.cs" />
<Compile Include="Online\Chat\Channel.cs" /> <Compile Include="Online\Chat\Channel.cs" />
<Compile Include="Online\Chat\Drawables\DrawableChannel.cs" /> <Compile Include="Online\Chat\Drawables\DrawableChannel.cs" />
<Compile Include="Online\Chat\Drawables\ChatLine.cs" /> <Compile Include="Online\Chat\Drawables\ChatLine.cs" />
@ -265,7 +267,6 @@
<Compile Include="Screens\Tournament\GroupContainer.cs" /> <Compile Include="Screens\Tournament\GroupContainer.cs" />
<Compile Include="Screens\Tournament\Teams\ITeamList.cs" /> <Compile Include="Screens\Tournament\Teams\ITeamList.cs" />
<Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" /> <Compile Include="Screens\Tournament\ScrollingTeamContainer.cs" />
<Compile Include="Screens\Tournament\Teams\Team.cs" />
<Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" /> <Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" />
<Compile Include="Users\User.cs" /> <Compile Include="Users\User.cs" />
<Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" /> <Compile Include="Graphics\UserInterface\Volume\VolumeControl.cs" />
@ -354,6 +355,13 @@
<Compile Include="Overlays\WaveOverlayContainer.cs" /> <Compile Include="Overlays\WaveOverlayContainer.cs" />
<Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" /> <Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" />
<Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" /> <Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" />
<Compile Include="Screens\Select\Leaderboards\Leaderboard.cs" />
<Compile Include="Screens\Select\Leaderboards\LeaderboardScore.cs" />
<Compile Include="Users\Country.cs" />
<Compile Include="Users\Team.cs" />
<Compile Include="Modes\ScoreRank.cs" />
<Compile Include="Users\Avatar.cs" />
<Compile Include="Screens\Select\Leaderboards\DrawableRank.cs" />
<Compile Include="Graphics\UserInterface\OsuTabControl.cs" /> <Compile Include="Graphics\UserInterface\OsuTabControl.cs" />
<Compile Include="Graphics\UserInterface\OsuTabItem.cs" /> <Compile Include="Graphics\UserInterface\OsuTabItem.cs" />
</ItemGroup> </ItemGroup>
@ -377,6 +385,7 @@
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.