diff --git a/osu-framework b/osu-framework
index 14a33d110e..cb48c7bef8 160000
--- a/osu-framework
+++ b/osu-framework
@@ -1 +1 @@
-Subproject commit 14a33d110e2ed32e3a875bc2acd2bade244ba045
+Subproject commit cb48c7bef8c5909472c70e09059ee6ea5bf6fc8a
diff --git a/osu-resources b/osu-resources
index f6042e1cb3..a4418111f8 160000
--- a/osu-resources
+++ b/osu-resources
@@ -1 +1 @@
-Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5
+Subproject commit a4418111f8ed2350a6fd46fe69258884f0757745
diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
index c6474eae5a..c090342a4b 100644
--- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
+++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
@@ -9,7 +9,7 @@
Properties
osu.Desktop.Deploy
osu.Desktop.Deploy
- v4.5.2
+ v4.6.1
512
true
diff --git a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs
index 11a15cf56f..d0f631201a 100644
--- a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs
+++ b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs
@@ -12,50 +12,104 @@ namespace osu.Desktop.Tests.Visual
{
public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
- private readonly BeatmapDetails details;
-
public TestCaseBeatmapDetails()
{
+ BeatmapDetails details;
Add(details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(150),
- Beatmap = new BeatmapInfo
+ });
+
+ AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo
+ {
+ Version = "All Metrics",
+ Metadata = new BeatmapMetadata
{
- Version = "VisualTest",
- Metadata = new BeatmapMetadata
- {
- Source = "Some guy",
- Tags = "beatmap metadata example with a very very long list of tags and not much creativity",
- },
- Difficulty = new BeatmapDifficulty
- {
- CircleSize = 7,
- ApproachRate = 3.5f,
- OverallDifficulty = 5.7f,
- DrainRate = 1,
- },
- StarDifficulty = 5.3f,
- Metrics = new BeatmapMetrics
- {
- Ratings = Enumerable.Range(0, 10),
- Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6),
- Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6),
- },
+ Source = "osu!lazer",
+ Tags = "this beatmap has all the metrics",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 7,
+ DrainRate = 1,
+ OverallDifficulty = 5.7f,
+ ApproachRate = 3.5f,
+ },
+ StarDifficulty = 5.3f,
+ Metrics = new BeatmapMetrics
+ {
+ Ratings = Enumerable.Range(0, 10),
+ Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
+ Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
},
});
- AddRepeatStep("fail values", newRetryAndFailValues, 10);
- }
+ AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo
+ {
+ Version = "Only Ratings",
+ Metadata = new BeatmapMetadata
+ {
+ Source = "osu!lazer",
+ Tags = "this beatmap has ratings metrics but not retries or fails",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 6,
+ DrainRate = 9,
+ OverallDifficulty = 6,
+ ApproachRate = 6,
+ },
+ StarDifficulty = 4.8f,
+ Metrics = new BeatmapMetrics
+ {
+ Ratings = Enumerable.Range(0, 10),
+ },
+ });
- private int lastRange = 1;
+ AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo
+ {
+ Version = "Only Retries and Fails",
+ Metadata = new BeatmapMetadata
+ {
+ Source = "osu!lazer",
+ Tags = "this beatmap has retries and fails but no ratings",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 3.7f,
+ DrainRate = 6,
+ OverallDifficulty = 6,
+ ApproachRate = 7,
+ },
+ StarDifficulty = 2.91f,
+ Metrics = new BeatmapMetrics
+ {
+ Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
+ Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
+ },
+ });
- private void newRetryAndFailValues()
- {
- details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6);
- details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6);
- details.Beatmap = details.Beatmap;
- lastRange += 100;
+ AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo
+ {
+ Version = "No Metrics",
+ Metadata = new BeatmapMetadata
+ {
+ Source = "osu!lazer",
+ Tags = "this beatmap has no metrics",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 5,
+ DrainRate = 5,
+ OverallDifficulty = 5.5f,
+ ApproachRate = 6.5f,
+ },
+ StarDifficulty = 1.97f,
+ Metrics = new BeatmapMetrics(),
+ });
+
+ AddStep("null beatmap", () => details.Beatmap = null);
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Desktop.Tests/Visual/TestCaseDirect.cs b/osu.Desktop.Tests/Visual/TestCaseDirect.cs
index b78ea02767..9fd93c3f1e 100644
--- a/osu.Desktop.Tests/Visual/TestCaseDirect.cs
+++ b/osu.Desktop.Tests/Visual/TestCaseDirect.cs
@@ -41,12 +41,14 @@ namespace osu.Desktop.Tests.Visual
{
new BeatmapSetInfo
{
+ OnlineBeatmapSetID = 578332,
Metadata = new BeatmapMetadata
{
Title = @"OrVid",
Artist = @"An",
Author = @"RLC",
Source = @"",
+ Tags = @"acuticnotes an-fillnote revid tear tearvid encrpted encryption axi axivid quad her hervid recoll",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@@ -71,12 +73,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
+ OnlineBeatmapSetID = 599627,
Metadata = new BeatmapMetadata
{
Title = @"tiny lamp",
Artist = @"fhana",
Author = @"Sotarks",
Source = @"ぎんぎつね",
+ Tags = @"lantis junichi sato yuxuki waga kevin mitsunaga towana gingitsune opening op full ver version kalibe collab collaboration",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@@ -101,12 +105,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
+ OnlineBeatmapSetID = 513268,
Metadata = new BeatmapMetadata
{
Title = @"At Gwanghwamun",
Artist = @"KYUHYUN",
Author = @"Cerulean Veyron",
Source = @"",
+ Tags = @"soul ballad kh super junior sj suju 슈퍼주니어 kt뮤직 sm엔터테인먼트 s.m.entertainment kt music 1st mini album ep",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@@ -146,12 +152,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
+ OnlineBeatmapSetID = 586841,
Metadata = new BeatmapMetadata
{
Title = @"RHAPSODY OF BLUE SKY",
Artist = @"fhana",
Author = @"[Kamiya]",
Source = @"小林さんちのメイドラゴン",
+ Tags = @"kobayashi san chi no maidragon aozora no opening anime maid dragon oblivion karen dynamix imoutosan pata-mon gxytcgxytc",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs
new file mode 100644
index 0000000000..9cb3053ff2
--- /dev/null
+++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs
@@ -0,0 +1,84 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Screens.Edit.Menus;
+
+namespace osu.Desktop.Tests.Visual
+{
+ public class TestCaseEditorMenuBar : OsuTestCase
+ {
+ public TestCaseEditorMenuBar()
+ {
+ Add(new EditorMenuBar
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Y = 50,
+ Items = new[]
+ {
+ new EditorMenuBarItem("File")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Clear All Notes"),
+ new EditorMenuItem("Open Difficulty..."),
+ new EditorMenuItem("Save"),
+ new EditorMenuItem("Create a new Difficulty..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Revert to Saved"),
+ new EditorMenuItem("Revert to Saved (Full)"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Test Beatmap"),
+ new EditorMenuItem("Open AiMod"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Upload Beatmap..."),
+ new EditorMenuItem("Export Package"),
+ new EditorMenuItem("Export Map Package"),
+ new EditorMenuItem("Import from..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Open Song Folder"),
+ new EditorMenuItem("Open .osu in Notepad"),
+ new EditorMenuItem("Open .osb in Notepad"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Exit"),
+ }
+ },
+ new EditorMenuBarItem("Timing")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Time Signature"),
+ new EditorMenuItem("Metronome Clicks"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Add Timing Section"),
+ new EditorMenuItem("Add Inheriting Section"),
+ new EditorMenuItem("Reset Current Section"),
+ new EditorMenuItem("Delete Timing Section"),
+ new EditorMenuItem("Resnap Current Section"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Timing Setup"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive),
+ new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive),
+ new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive),
+ new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Set Current Position as Preview Point"),
+ }
+ },
+ new EditorMenuBarItem("Testing")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Item 1"),
+ new EditorMenuItem("Item 2"),
+ new EditorMenuItem("Item 3"),
+ }
+ },
+ }
+ });
+ }
+ }
+}
diff --git a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs
index 5f8ee8795c..f67db2f41a 100644
--- a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs
+++ b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs
@@ -1,13 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using OpenTK;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
-using OpenTK;
namespace osu.Desktop.Tests.Visual
{
@@ -24,7 +24,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.XH,
- Accuracy = 100,
+ Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -42,7 +42,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.X,
- Accuracy = 100,
+ Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -60,7 +60,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.SH,
- Accuracy = 100,
+ Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -78,7 +78,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.S,
- Accuracy = 100,
+ Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -96,7 +96,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.A,
- Accuracy = 100,
+ Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -114,7 +114,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.B,
- Accuracy = 98.26,
+ Accuracy = 0.9826,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -132,7 +132,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.C,
- Accuracy = 96.54,
+ Accuracy = 0.9654,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -150,7 +150,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
- Accuracy = 60.25,
+ Accuracy = 0.6025,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -168,7 +168,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
- Accuracy = 51.40,
+ Accuracy = 0.5140,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@@ -186,7 +186,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
- Accuracy = 42.22,
+ Accuracy = 0.4222,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs
index 76235bbf19..d855e86aa0 100644
--- a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs
+++ b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs
@@ -41,8 +41,20 @@ namespace osu.Desktop.Tests.Visual
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
- new DrawableNote(new Note { StartTime = 5000 }, ManiaAction.Key1) { AccentColour = Color4.Red },
- new DrawableNote(new Note { StartTime = 6000 }, ManiaAction.Key1) { AccentColour = Color4.Red }
+ new DrawableNote(new Note(), ManiaAction.Key1)
+ {
+ Y = 5000,
+ LifetimeStart = double.MinValue,
+ LifetimeEnd = double.MaxValue,
+ AccentColour = Color4.Red
+ },
+ new DrawableNote(new Note(), ManiaAction.Key1)
+ {
+ Y = 6000,
+ LifetimeStart = double.MinValue,
+ LifetimeEnd = double.MaxValue,
+ AccentColour = Color4.Red
+ }
}
}
}
@@ -63,11 +75,14 @@ namespace osu.Desktop.Tests.Visual
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
- new DrawableHoldNote(new HoldNote
+ new DrawableHoldNote(new HoldNote(), ManiaAction.Key1)
{
- StartTime = 5000,
- Duration = 1000
- }, ManiaAction.Key1) { AccentColour = Color4.Red }
+ Y = 5000,
+ Height = 1000,
+ LifetimeStart = double.MinValue,
+ LifetimeEnd = double.MaxValue,
+ AccentColour = Color4.Red
+ }
}
}
}
diff --git a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs
index 379100b543..8d1ae7d913 100644
--- a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs
+++ b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs
@@ -32,7 +32,7 @@ namespace osu.Desktop.Tests.Visual
backingDatabase.CreateTable();
rulesets = new RulesetStore(backingDatabase);
- manager = new BeatmapManager(storage, null, backingDatabase, rulesets);
+ manager = new BeatmapManager(storage, null, backingDatabase, rulesets, null);
for (int i = 0; i < 100; i += 10)
manager.Import(createTestBeatmapSet(i));
diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
index 24d112a45c..975af1a782 100644
--- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj
+++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj
@@ -9,7 +9,7 @@
Properties
osu.Desktop.Tests
osu.Desktop.Tests
- v4.5
+ v4.6.1
512
@@ -87,6 +87,7 @@
+
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index 8bba59207f..33019909c6 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -22,7 +22,7 @@
OnOutputUpdated
false
LocalIntranet
- v4.5
+ v4.6.1
true
publish\
true
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index bbca4145c6..661c17699b 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -22,7 +22,7 @@
OnOutputUpdated
false
LocalIntranet
- v4.5
+ v4.6.1
true
publish\
true
diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs
index 96f8a8df9b..214cbc7f50 100644
--- a/osu.Game.Rulesets.Catch/CatchRuleset.cs
+++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs
@@ -93,8 +93,6 @@ namespace osu.Game.Rulesets.Catch
}
}
- public override Mod GetAutoplayMod() => new ModAutoplay();
-
public override string Description => "osu!catch";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
index f416f6acfb..0e7fbffbb6 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Catch.UI
var additive = createCatcherSprite();
additive.RelativePositionAxes = Axes.Both;
- additive.BlendingMode = BlendingMode.Additive;
+ additive.Blending = BlendingMode.Additive;
additive.Position = Position;
additive.Scale = Scale;
diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
index 79ef5f4ba8..2ae2262ac7 100644
--- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
+++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
@@ -9,7 +9,7 @@
Properties
osu.Game.Rulesets.Catch
osu.Game.Rulesets.Catch
- v4.5
+ v4.6.1
512
diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
index ed46da4f85..d852a54ab6 100644
--- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Mania
}
}
- public override Mod GetAutoplayMod() => new ModAutoplay();
-
public override string Description => "osu!mania";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
index f44ad6fd60..bb11a05fc8 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
@@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModFadeIn : Mod
{
public override string Name => "FadeIn";
+ public override string ShortenedName => "FI";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override ModType Type => ModType.DifficultyIncrease;
public override double ScoreMultiplier => 1;
@@ -78,12 +79,14 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModRandom : Mod
{
public override string Name => "Random";
+ public override string ShortenedName => "RD";
public override string Description => @"Shuffle around the notes!";
public override double ScoreMultiplier => 1;
}
public abstract class ManiaKeyMod : Mod
{
+ public override string ShortenedName => Name;
public abstract int KeyCount { get; }
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
public override bool Ranked => true;
@@ -146,6 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModKeyCoop : Mod
{
public override string Name => "KeyCoop";
+ public override string ShortenedName => "2P";
public override string Description => @"Double the key amount, double the fun!";
public override double ScoreMultiplier => 1;
public override bool Ranked => true;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
index a054e0db56..132c49ab31 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
@@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModGravity : Mod, IGenerateSpeedAdjustments
{
public override string Name => "Gravity";
+ public override string ShortenedName => "GR";
public override double ScoreMultiplier => 0;
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
index e06f71cb64..3b801cba01 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
@@ -9,6 +10,7 @@ using OpenTK;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
namespace osu.Game.Rulesets.Mania.Objects.Drawables
@@ -23,6 +25,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
private readonly BodyPiece bodyPiece;
private readonly Container tickContainer;
+ private readonly Container glowContainer;
///
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
@@ -42,13 +45,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddRange(new Drawable[]
{
- // For now the body piece covers the entire height of the container
- // whereas possibly in the future we don't want to extend under the head/tail.
- // This will be fixed when new designs are given or the current design is finalized.
bodyPiece = new BodyPiece
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.X,
},
tickContainer = new Container
{
@@ -65,6 +66,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.TopCentre
+ },
+ // The hit object itself cannot be used for the glow because the tail overshoots it
+ // So a specialized container that is updated to contain the tail height is used
+ glowContainer = new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ Masking = true,
+ Child = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0,
+ AlwaysPresent = true
+ }
}
});
@@ -83,6 +97,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddNested(tail);
}
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ updateGlow();
+ }
+
public override Color4 AccentColour
{
get { return base.AccentColour; }
@@ -97,13 +118,42 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
bodyPiece.AccentColour = value;
head.AccentColour = value;
tail.AccentColour = value;
+
+ updateGlow();
}
}
+ private void updateGlow()
+ {
+ if (!IsLoaded)
+ return;
+
+ glowContainer.EdgeEffect = new EdgeEffectParameters
+ {
+ Type = EdgeEffectType.Glow,
+ Colour = AccentColour.Opacity(0.5f),
+ Radius = 10,
+ Hollow = true
+ };
+ }
+
protected override void UpdateState(ArmedState state)
{
}
+ protected override void Update()
+ {
+ base.Update();
+
+ // Make the body piece not lie under the head note
+ bodyPiece.Y = head.Height;
+ bodyPiece.Height = DrawHeight - head.Height;
+
+ // Make the glowContainer "contain" the height of the tail note, keeping in mind
+ // that the tail note overshoots the height of this hit object
+ glowContainer.Height = DrawHeight + tail.Height;
+ }
+
public bool OnPressed(ManiaAction action)
{
// Make sure the action happened within the body of the hold note
@@ -153,6 +203,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativePositionAxes = Axes.None;
Y = 0;
+
+ // Life time managed by the parent DrawableHoldNote
+ LifetimeStart = double.MinValue;
+ LifetimeEnd = double.MaxValue;
+
+ ApplyGlow = false;
}
public override bool OnPressed(ManiaAction action)
@@ -190,6 +246,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativePositionAxes = Axes.None;
Y = 0;
+
+ // Life time managed by the parent DrawableHoldNote
+ LifetimeStart = double.MinValue;
+ LifetimeEnd = double.MaxValue;
+
+ ApplyGlow = false;
}
protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement();
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
index 39abbb6b3d..7f4ec8d8d2 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
@@ -23,11 +23,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
///
public Func HoldStartTime;
- ///
- /// References whether the user is currently holding the hold note.
- ///
- public Func IsHolding;
-
private readonly Container glowContainer;
public DrawableHoldNoteTick(HoldNoteTick hitObject)
@@ -36,9 +31,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
+ Y = (float)HitObject.StartTime;
+
RelativeSizeAxes = Axes.X;
Size = new Vector2(1);
+ // Life time managed by the parent DrawableHoldNote
+ LifetimeStart = double.MinValue;
+ LifetimeEnd = double.MaxValue;
+
Children = new[]
{
glowContainer = new CircularContainer
@@ -112,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (Judgement.Result != HitResult.None)
return;
- if (IsHolding?.Invoke() != true)
+ if (HoldStartTime?.Invoke() == null)
return;
UpdateJudgement(true);
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
index bfef05ea07..f6129602a8 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using osu.Framework.Graphics;
using OpenTK.Graphics;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
@@ -20,6 +21,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
: base(hitObject)
{
+ RelativePositionAxes = Axes.Y;
HitObject = hitObject;
if (action != null)
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
index c201ab7bd0..a58ae9b31c 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
@@ -2,8 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
+using osu.Framework.Extensions.Color4Extensions;
using OpenTK.Graphics;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
@@ -16,13 +18,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
///
public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler
{
+ ///
+ /// Gets or sets whether this should apply glow to itself.
+ ///
+ protected bool ApplyGlow = true;
+
private readonly NotePiece headPiece;
public DrawableNote(Note hitObject, ManiaAction action)
: base(hitObject, action)
{
RelativeSizeAxes = Axes.X;
- Height = 100;
+ AutoSizeAxes = Axes.Y;
+ Masking = true;
Add(headPiece = new NotePiece
{
@@ -31,6 +39,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
});
}
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ updateGlow();
+ }
+
public override Color4 AccentColour
{
get { return base.AccentColour; }
@@ -41,9 +56,28 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
base.AccentColour = value;
headPiece.AccentColour = value;
+
+ updateGlow();
}
}
+ private void updateGlow()
+ {
+ if (!IsLoaded)
+ return;
+
+ if (!ApplyGlow)
+ return;
+
+ EdgeEffect = new EdgeEffectParameters
+ {
+ Type = EdgeEffectType.Glow,
+ Colour = AccentColour.Opacity(0.5f),
+ Radius = 10,
+ Hollow = true
+ };
+ }
+
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
index 04e8df4ae2..fe40532e42 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
@@ -1,7 +1,10 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
+using osu.Framework.Caching;
using OpenTK.Graphics;
+using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -14,22 +17,61 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
///
internal class BodyPiece : Container, IHasAccentColour
{
- private readonly Box box;
+ private readonly Container subtractionLayer;
+
+ private readonly Drawable background;
+ private readonly BufferedContainer foreground;
+ private readonly BufferedContainer subtractionContainer;
public BodyPiece()
{
- RelativeSizeAxes = Axes.Both;
+ Blending = BlendingMode.Additive;
Children = new[]
{
- box = new Box
+ background = new Box { RelativeSizeAxes = Axes.Both },
+ foreground = new BufferedContainer
{
RelativeSizeAxes = Axes.Both,
- Alpha = 0.3f
+ CacheDrawnFrameBuffer = true,
+ Children = new Drawable[]
+ {
+ new Box { RelativeSizeAxes = Axes.Both },
+ subtractionContainer = new BufferedContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ // This is needed because we're blending with another object
+ BackgroundColour = Color4.White.Opacity(0),
+ CacheDrawnFrameBuffer = true,
+ // The 'hole' is achieved by subtracting the result of this container with the parent
+ Blending = new BlendingParameters { AlphaEquation = BlendingEquation.ReverseSubtract },
+ Child = subtractionLayer = new CircularContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ // Height computed in Update
+ Width = 1,
+ Masking = true,
+ Child = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0,
+ AlwaysPresent = true
+ }
+ }
+ }
+ }
}
};
}
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ updateAccentColour();
+ }
+
private Color4 accentColour;
public Color4 AccentColour
{
@@ -40,8 +82,51 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
return;
accentColour = value;
- box.Colour = accentColour;
+ updateAccentColour();
}
}
+
+ private Cached subtractionCache = new Cached();
+
+ public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
+ {
+ if ((invalidation & Invalidation.DrawSize) > 0)
+ subtractionCache.Invalidate();
+
+ return base.Invalidate(invalidation, source, shallPropagate);
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (!subtractionCache.IsValid)
+ {
+ subtractionLayer.Width = 5;
+ subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth);
+ subtractionLayer.EdgeEffect = new EdgeEffectParameters
+ {
+ Colour = Color4.White,
+ Type = EdgeEffectType.Glow,
+ Radius = DrawWidth
+ };
+
+ foreground.ForceRedraw();
+ subtractionContainer.ForceRedraw();
+
+ subtractionCache.Validate();
+ }
+ }
+
+ private void updateAccentColour()
+ {
+ if (!IsLoaded)
+ return;
+
+ foreground.Colour = AccentColour.Opacity(0.4f);
+ background.Colour = AccentColour.Opacity(0.2f);
+
+ subtractionCache.Invalidate();
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index a8f5b4919d..d5bc7cc659 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Mania.UI
{
if (action == Action)
{
- background.FadeTo(background.Alpha + 0.2f, 50, Easing.OutQuint);
+ background.FadeTo(0.6f, 50, Easing.OutQuint);
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint);
}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index d3dc920fc6..ce91fda023 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers;
using System;
using osu.Game.Graphics;
using osu.Framework.Allocation;
-using OpenTK.Input;
using System.Linq;
using System.Collections.Generic;
using osu.Framework.Configuration;
@@ -25,12 +24,6 @@ namespace osu.Game.Rulesets.Mania.UI
{
public const float HIT_TARGET_POSITION = 50;
- ///
- /// Default column keys, expanding outwards from the middle as more column are added.
- /// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc...
- ///
- private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon };
-
private SpecialColumnPosition specialColumnPosition;
///
/// The style to use for the special column.
diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
index 890c9116cf..5f39054d82 100644
--- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
+++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
@@ -9,7 +9,7 @@
Properties
osu.Game.Rulesets.Mania
osu.Game.Rulesets.Mania
- v4.5
+ v4.6.1
512
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs
index 432c6d391c..2970055bff 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs
@@ -96,6 +96,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModSpunOut : Mod
{
public override string Name => "Spun Out";
+ public override string ShortenedName => "SO";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout;
public override string Description => @"Spinners will be automatically completed";
public override double ScoreMultiplier => 0.9;
@@ -106,6 +107,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModAutopilot : Mod
{
public override string Name => "Autopilot";
+ public override string ShortenedName => "AP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
public override double ScoreMultiplier => 0;
@@ -126,6 +128,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModTarget : Mod
{
public override string Name => "Target";
+ public override string ShortenedName => "TP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_target;
public override string Description => @"";
public override double ScoreMultiplier => 1;
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
index 30e6172802..dbf5c6c541 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
@@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
new Box
{
Size = new Vector2(width),
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0.5f,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
index 0c3c4f0a6d..a7384b8f8e 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
new TrianglesPiece
{
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Alpha = 0.5f,
}
};
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
index e5cf10b88a..7912108901 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
@@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- BlendingMode = BlendingMode.Additive;
+ Blending = BlendingMode.Additive;
Alpha = 0;
Children = new Drawable[]
{
new TrianglesPiece
{
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
index 97d7de35cf..a80d163246 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- BlendingMode = BlendingMode.Additive;
+ Blending = BlendingMode.Additive;
Alpha = 0;
Children = new Drawable[]
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
index 8a7b353da1..0adfed2710 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Alpha = 0.5f
}
};
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
index 0bcb8a4986..1986b1431b 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.slider = slider;
Masking = true;
AutoSizeAxes = Axes.Both;
- BlendingMode = BlendingMode.Additive;
+ Blending = BlendingMode.Additive;
Origin = Anchor.Centre;
BorderThickness = 10;
BorderColour = Color4.Orange;
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
index 680f987274..2082e9a27b 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
@@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
path = new Path
{
- BlendingMode = BlendingMode.None,
+ Blending = BlendingMode.None,
},
}
},
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
index 942f166241..a06aaff7fb 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.isEnd = isEnd;
AutoSizeAxes = Axes.Both;
- BlendingMode = BlendingMode.Additive;
+ Blending = BlendingMode.Additive;
Origin = Anchor.Centre;
Children = new Drawable[]
diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs
index 72ba421344..c6ecc3a506 100644
--- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs
+++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs
@@ -51,6 +51,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing
foreach (OsuDifficultyHitObject h in onScreen)
{
+ // ReSharper disable once PossibleNullReferenceException (resharper not smart enough to understand IEnumerator.MoveNext())
h.TimeUntilHit -= latest.DeltaTime;
// Calculate reading strain here
}
diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs
index 00413331e0..c943518b0b 100644
--- a/osu.Game.Rulesets.Osu/OsuRuleset.cs
+++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs
@@ -112,8 +112,6 @@ namespace osu.Game.Rulesets.Osu
}
}
- public override Mod GetAutoplayMod() => new OsuModAutoplay();
-
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap);
diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index 0c9e53cf69..857f47f9b9 100644
--- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -9,7 +9,7 @@
Properties
osu.Game.Rulesets.Osu
osu.Game.Rulesets.Osu
- v4.5
+ v4.6.1
512
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index 4eb5c46838..9648f50b22 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Origin = Anchor.Centre,
Alpha = 0,
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Masking = true,
Children = new[]
{
@@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = target_ring_thick_border,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Children = new Drawable[]
{
new Box
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index ba717371dd..3264b77bc4 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Alpha = 0,
AlwaysPresent = true
}
diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
index f457732085..7b1452766e 100644
--- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
@@ -95,8 +95,6 @@ namespace osu.Game.Rulesets.Taiko
}
}
- public override Mod GetAutoplayMod() => new TaikoModAutoplay();
-
public override string Description => "osu!taiko";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index 659f421ebe..5e79166bec 100644
--- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
},
centre = new Sprite
{
@@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f),
Alpha = 0,
- BlendingMode = BlendingMode.Additive
+ Blending = BlendingMode.Additive
}
};
}
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index 678de7f713..cfb8a67408 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
},
new HitTarget
{
@@ -126,14 +126,14 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- BlendingMode = BlendingMode.Additive
+ Blending = BlendingMode.Additive
},
judgementContainer = new Container
{
Name = "Judgements",
RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- BlendingMode = BlendingMode.Additive
+ Blending = BlendingMode.Additive
},
}
},
diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
index 33748a267f..e1987ec96d 100644
--- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
+++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
@@ -9,7 +9,7 @@
Properties
osu.Game.Rulesets.Taiko
osu.Game.Rulesets.Taiko
- v4.5
+ v4.6.1
512
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 8ec68b41be..220b1aac7f 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -7,7 +7,7 @@
Library
osu.Game.Tests
osu.Game.Tests
- v4.5
+ v4.6.1
true
diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs
index 82777734bb..15953fcd82 100644
--- a/osu.Game/Beatmaps/Beatmap.cs
+++ b/osu.Game/Beatmaps/Beatmap.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
public class Beatmap
where T : HitObject
{
- public BeatmapInfo BeatmapInfo;
+ public BeatmapInfo BeatmapInfo = new BeatmapInfo();
public ControlPointInfo ControlPointInfo = new ControlPointInfo();
public List Breaks = new List();
public readonly List ComboColors = new List
@@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps
///
/// The HitObjects this Beatmap contains.
///
- public List HitObjects;
+ public List HitObjects = new List();
///
/// Total amount of break time in the beatmap.
@@ -44,12 +44,13 @@ namespace osu.Game.Beatmaps
/// Constructs a new beatmap.
///
/// The original beatmap to use the parameters of.
- public Beatmap(Beatmap original = null)
+ public Beatmap(Beatmap original = null)
{
BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo;
ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo;
Breaks = original?.Breaks ?? Breaks;
ComboColors = original?.ComboColors ?? ComboColors;
+ HitObjects = original?.HitObjects ?? HitObjects;
}
}
@@ -65,7 +66,6 @@ namespace osu.Game.Beatmaps
public Beatmap(Beatmap original = null)
: base(original)
{
- HitObjects = original?.HitObjects;
}
}
}
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index 551612330b..f58b3505c5 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -20,6 +20,9 @@ using osu.Game.IPC;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
using SQLite.Net;
+using osu.Game.Online.API.Requests;
+using System.Threading.Tasks;
+using osu.Game.Online.API;
namespace osu.Game.Beatmaps
{
@@ -63,6 +66,10 @@ namespace osu.Game.Beatmaps
private readonly BeatmapStore beatmaps;
+ private readonly APIAccess api;
+
+ private readonly List currentDownloads = new List();
+
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private BeatmapIPCChannel ipc;
@@ -76,7 +83,7 @@ namespace osu.Game.Beatmaps
///
public Func GetStableStorage { private get; set; }
- public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null)
+ public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null)
{
beatmaps = new BeatmapStore(connection);
beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s);
@@ -88,6 +95,7 @@ namespace osu.Game.Beatmaps
this.files = files;
this.connection = connection;
this.rulesets = rulesets;
+ this.api = api;
if (importHost != null)
ipc = new BeatmapIPCChannel(importHost, this);
@@ -177,6 +185,74 @@ namespace osu.Game.Beatmaps
beatmaps.Add(beatmapSetInfo);
}
+ ///
+ /// Downloads a beatmap.
+ ///
+ /// The to be downloaded.
+ /// A new , or an existing one if a download is already in progress.
+ public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo)
+ {
+ var existing = GetExistingDownload(beatmapSetInfo);
+
+ if (existing != null) return existing;
+
+ if (api == null) return null;
+
+ ProgressNotification downloadNotification = new ProgressNotification
+ {
+ Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
+ };
+
+ var request = new DownloadBeatmapSetRequest(beatmapSetInfo);
+
+ request.DownloadProgressed += progress =>
+ {
+ downloadNotification.State = ProgressNotificationState.Active;
+ downloadNotification.Progress = progress;
+ };
+
+ request.Success += data =>
+ {
+ downloadNotification.State = ProgressNotificationState.Completed;
+
+ using (var stream = new MemoryStream(data))
+ using (var archive = new OszArchiveReader(stream))
+ Import(archive);
+
+ currentDownloads.Remove(request);
+ };
+
+ request.Failure += data =>
+ {
+ downloadNotification.State = ProgressNotificationState.Completed;
+ Logger.Error(data, "Failed to get beatmap download information");
+ currentDownloads.Remove(request);
+ };
+
+ downloadNotification.CancelRequested += () =>
+ {
+ request.Cancel();
+ currentDownloads.Remove(request);
+ downloadNotification.State = ProgressNotificationState.Cancelled;
+ return true;
+ };
+
+ currentDownloads.Add(request);
+ PostNotification?.Invoke(downloadNotification);
+
+ // don't run in the main api queue as this is a long-running task.
+ Task.Run(() => request.Perform(api));
+
+ return request;
+ }
+
+ ///
+ /// Get an existing download request if it exists.
+ ///
+ /// The whose download request is wanted.
+ /// The object if it exists, or null.
+ public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID);
+
///
/// Delete a beatmap from the manager.
/// Is a no-op for already deleted beatmaps.
diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
index 479f274efb..ad0b110e48 100644
--- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
@@ -7,7 +7,6 @@ using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
-using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@@ -42,10 +41,7 @@ namespace osu.Game.Beatmaps
this.game = game;
}
- protected override Beatmap GetBeatmap() => new Beatmap
- {
- HitObjects = new List(),
- };
+ protected override Beatmap GetBeatmap() => new Beatmap();
protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4");
@@ -59,8 +55,6 @@ namespace osu.Game.Beatmaps
{
public override IEnumerable GetModsFor(ModType type) => new Mod[] { };
- public override Mod GetAutoplayMod() => new ModAutoplay();
-
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset)
{
throw new NotImplementedException();
diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
index 234d65eee4..81695c3b5a 100644
--- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using osu.Game.Rulesets.Objects;
namespace osu.Game.Beatmaps.Formats
{
@@ -21,7 +20,7 @@ namespace osu.Game.Beatmaps.Formats
{
string line;
do { line = stream.ReadLine()?.Trim(); }
- while (line != null && line.Length == 0);
+ while (line != null && line.Length == 0);
if (line == null || !decoders.ContainsKey(line))
throw new IOException(@"Unknown file format");
@@ -47,7 +46,6 @@ namespace osu.Game.Beatmaps.Formats
{
var beatmap = new Beatmap
{
- HitObjects = new List(),
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata(),
diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs
index 3793f20222..e6a26baa66 100644
--- a/osu.Game/Beatmaps/WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmap.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps
{
if (beatmap != null) return beatmap;
- beatmap = GetBeatmap();
+ beatmap = GetBeatmap() ?? new Beatmap();
// use the database-backed info.
beatmap.BeatmapInfo = BeatmapInfo;
diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs
index ea02feef0e..053ed9c191 100644
--- a/osu.Game/Graphics/Cursor/MenuCursor.cs
+++ b/osu.Game/Graphics/Cursor/MenuCursor.cs
@@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Cursor
},
AdditiveLayer = new Sprite
{
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = colour.Pink,
Alpha = 0,
Texture = textures.Get(@"Cursor/menu-cursor-additive"),
diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs
index 1cbf77d8f2..289ccbf5cd 100644
--- a/osu.Game/Graphics/UserInterface/DialogButton.cs
+++ b/osu.Game/Graphics/UserInterface/DialogButton.cs
@@ -99,7 +99,8 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.ResizeTo(new Vector2(1.5f, 1f), click_duration, Easing.In);
flash();
- this.Delay(click_duration).Schedule(delegate {
+ this.Delay(click_duration).Schedule(delegate
+ {
colourContainer.ResizeTo(new Vector2(0.8f, 1f));
spriteText.Spacing = Vector2.Zero;
glowContainer.FadeOut();
@@ -140,7 +141,7 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.Add(flash);
flash.Colour = ButtonColour;
- flash.BlendingMode = BlendingMode.Additive;
+ flash.Blending = BlendingMode.Additive;
flash.Alpha = 0.3f;
flash.FadeOutFromOne(click_duration);
flash.Expire();
diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs
index abc1b036bc..32a37a4910 100644
--- a/osu.Game/Graphics/UserInterface/OsuButton.cs
+++ b/osu.Game/Graphics/UserInterface/OsuButton.cs
@@ -63,7 +63,7 @@ namespace osu.Game.Graphics.UserInterface
hover = new Box
{
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = Color4.White.Opacity(0.1f),
Alpha = 0,
},
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index b69186e8b0..f605804aaa 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -96,7 +96,7 @@ namespace osu.Game.Graphics.UserInterface
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour };
#region DrawableOsuDropdownMenuItem
- protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
+ public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
{
private Color4? accentColour;
public Color4 AccentColour
diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs
index 103155dd1f..3fd5481152 100644
--- a/osu.Game/Graphics/UserInterface/OsuMenu.cs
+++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs
@@ -18,8 +18,8 @@ namespace osu.Game.Graphics.UserInterface
{
public class OsuMenu : Menu
{
- public OsuMenu(Direction direction)
- : base(direction)
+ public OsuMenu(Direction direction, bool topLevelMenu = false)
+ : base(direction, topLevelMenu)
{
BackgroundColour = Color4.Black.Opacity(0.5f);
@@ -46,6 +46,11 @@ namespace osu.Game.Graphics.UserInterface
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item);
+ protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical)
+ {
+ Anchor = Direction == Direction.Horizontal ? Anchor.BottomLeft : Anchor.TopRight
+ };
+
protected class DrawableOsuMenuItem : DrawableMenuItem
{
private const int margin_horizontal = 17;
@@ -61,7 +66,6 @@ namespace osu.Game.Graphics.UserInterface
public DrawableOsuMenuItem(MenuItem item)
: base(item)
{
-
}
[BackgroundDependencyLoader]
@@ -114,9 +118,10 @@ namespace osu.Game.Graphics.UserInterface
return base.OnClick(state);
}
- protected override Drawable CreateContent() => text = new TextContainer();
+ protected sealed override Drawable CreateContent() => text = CreateTextContainer();
+ protected virtual TextContainer CreateTextContainer() => new TextContainer();
- private class TextContainer : Container, IHasText
+ protected class TextContainer : Container, IHasText
{
public string Text
{
diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs
index 4c108e793a..8c777f491b 100644
--- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs
+++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs
@@ -15,11 +15,7 @@ namespace osu.Game.Graphics.UserInterface.Volume
{
private readonly VolumeMeter volumeMeterMaster;
- private void volumeChanged(double newVolume)
- {
- Show();
- schedulePopOut();
- }
+ protected override bool BlockPassThroughMouse => false;
public VolumeControl()
{
@@ -85,6 +81,12 @@ namespace osu.Game.Graphics.UserInterface.Volume
return false;
}
+ private void volumeChanged(double newVolume)
+ {
+ Show();
+ schedulePopOut();
+ }
+
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs
new file mode 100644
index 0000000000..5a9f609bca
--- /dev/null
+++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs
@@ -0,0 +1,24 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Beatmaps;
+using System;
+
+namespace osu.Game.Online.API.Requests
+{
+ public class DownloadBeatmapSetRequest : APIDownloadRequest
+ {
+ public readonly BeatmapSetInfo BeatmapSet;
+
+ public Action DownloadProgressed;
+
+ public DownloadBeatmapSetRequest(BeatmapSetInfo set)
+ {
+ BeatmapSet = set;
+
+ Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total);
+ }
+
+ protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download";
+ }
+}
diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs
index 966049429e..ef9ee85d25 100644
--- a/osu.Game/Online/API/Requests/GetScoresRequest.cs
+++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs
@@ -1,10 +1,14 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
using System.Collections.Generic;
+using System.Linq;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Game.Beatmaps;
+using osu.Game.Users;
+using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Online.API.Requests
@@ -16,6 +20,14 @@ namespace osu.Game.Online.API.Requests
public GetScoresRequest(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
+
+ Success += onSuccess;
+ }
+
+ private void onSuccess(GetScoresResponse r)
+ {
+ foreach (OnlineScore score in r.Scores)
+ score.ApplyBeatmap(beatmap);
}
protected override WebRequest CreateWebRequest()
@@ -32,6 +44,88 @@ namespace osu.Game.Online.API.Requests
public class GetScoresResponse
{
[JsonProperty(@"scores")]
- public IEnumerable Scores;
+ public IEnumerable Scores;
}
-}
\ No newline at end of file
+
+ public class OnlineScore : Score
+ {
+ [JsonProperty(@"score")]
+ private double totalScore
+ {
+ set { TotalScore = value; }
+ }
+
+ [JsonProperty(@"max_combo")]
+ private int maxCombo
+ {
+ set { MaxCombo = value; }
+ }
+
+ [JsonProperty(@"user")]
+ private User user
+ {
+ set { User = value; }
+ }
+
+ [JsonProperty(@"replay_data")]
+ private Replay replay
+ {
+ set { Replay = value; }
+ }
+
+ [JsonProperty(@"score_id")]
+ private long onlineScoreID
+ {
+ set { OnlineScoreID = value; }
+ }
+
+ [JsonProperty(@"created_at")]
+ private DateTimeOffset date
+ {
+ set { Date = value; }
+ }
+
+ [JsonProperty(@"statistics")]
+ private Dictionary jsonStats
+ {
+ set
+ {
+ foreach (var kvp in value)
+ {
+ string key = kvp.Key;
+ switch (key)
+ {
+ case @"count_300":
+ key = @"300";
+ break;
+ case @"count_100":
+ key = @"100";
+ break;
+ case @"count_50":
+ key = @"50";
+ break;
+ case @"count_miss":
+ key = @"x";
+ break;
+ default:
+ continue;
+ }
+
+ Statistics.Add(key, kvp.Value);
+ }
+ }
+ }
+
+ [JsonProperty(@"mods")]
+ private string[] modStrings { get; set; }
+
+ public void ApplyBeatmap(BeatmapInfo beatmap)
+ {
+ Beatmap = beatmap;
+ Ruleset = beatmap.Ruleset;
+
+ // Evaluate the mod string
+ Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray();
+ }
+ }
+}
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index c020675881..b4fbdfb252 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -245,7 +245,11 @@ namespace osu.Game
LoadComponentAsync(Toolbar = new Toolbar
{
Depth = -4,
- OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); },
+ OnHome = delegate
+ {
+ hideAllOverlays();
+ intro?.ChildScreen?.MakeCurrent();
+ },
}, overlayContent.Add);
settings.StateChanged += delegate
@@ -310,6 +314,16 @@ namespace osu.Game
private OsuScreen currentScreen;
private FrameworkConfigManager frameworkConfig;
+ private void hideAllOverlays()
+ {
+ settings.State = Visibility.Hidden;
+ chat.State = Visibility.Hidden;
+ direct.State = Visibility.Hidden;
+ social.State = Visibility.Hidden;
+ userProfile.State = Visibility.Hidden;
+ notificationOverlay.State = Visibility.Hidden;
+ }
+
private void screenChanged(Screen newScreen)
{
currentScreen = newScreen as OsuScreen;
@@ -323,19 +337,12 @@ namespace osu.Game
//central game screen change logic.
if (!currentScreen.ShowOverlays)
{
- settings.State = Visibility.Hidden;
- Toolbar.State = Visibility.Hidden;
+ hideAllOverlays();
musicController.State = Visibility.Hidden;
- chat.State = Visibility.Hidden;
- direct.State = Visibility.Hidden;
- social.State = Visibility.Hidden;
- userProfile.State = Visibility.Hidden;
- notificationOverlay.State = Visibility.Hidden;
+ Toolbar.State = Visibility.Hidden;
}
else
- {
Toolbar.State = Visibility.Visible;
- }
ScreenChanged?.Invoke(newScreen);
}
diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs
index a7136ce803..76eb7d5101 100644
--- a/osu.Game/OsuGameBase.cs
+++ b/osu.Game/OsuGameBase.cs
@@ -106,9 +106,15 @@ namespace osu.Game
connection.CreateTable();
+ dependencies.Cache(API = new APIAccess
+ {
+ Username = LocalConfig.Get(OsuSetting.Username),
+ Token = LocalConfig.Get(OsuSetting.Token)
+ });
+
dependencies.Cache(RulesetStore = new RulesetStore(connection));
dependencies.Cache(FileStore = new FileStore(connection, Host.Storage));
- dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));
+ dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, API, Host));
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore));
dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore));
dependencies.Cache(new OsuColour());
@@ -144,12 +150,6 @@ namespace osu.Game
Beatmap = new NonNullableBindable(defaultBeatmap);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
- dependencies.Cache(API = new APIAccess
- {
- Username = LocalConfig.Get(OsuSetting.Username),
- Token = LocalConfig.Get(OsuSetting.Token)
- });
-
Beatmap.ValueChanged += b =>
{
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs
index f43154ea20..8360e793d8 100644
--- a/osu.Game/Overlays/Chat/ChannelListItem.cs
+++ b/osu.Game/Overlays/Chat/ChannelListItem.cs
@@ -76,7 +76,6 @@ namespace osu.Game.Overlays.Chat
Size = new Vector2(text_size),
Shadow = false,
Margin = new MarginPadding { Right = 10f },
- Alpha = 0f,
},
},
},
@@ -109,7 +108,6 @@ namespace osu.Game.Overlays.Chat
TextSize = text_size,
Font = @"Exo2.0-SemiBold",
Shadow = false,
- Alpha = 0.8f,
},
},
},
@@ -151,6 +149,9 @@ namespace osu.Game.Overlays.Chat
joinedBind.ValueChanged += updateColour;
joinedBind.BindTo(channel.Joined);
+
+ joinedBind.TriggerChange();
+ FinishTransforms(true);
}
protected override bool OnHover(InputState state)
diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs
index a642f72821..6f1f581d0b 100644
--- a/osu.Game/Overlays/Direct/DirectPanel.cs
+++ b/osu.Game/Overlays/Direct/DirectPanel.cs
@@ -4,8 +4,6 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
-using System.IO;
-using System.Threading.Tasks;
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -20,8 +18,8 @@ using osu.Framework.Input;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Framework.Logging;
-using osu.Game.Beatmaps.IO;
using osu.Game.Overlays.Notifications;
+using osu.Game.Online.API.Requests;
namespace osu.Game.Overlays.Direct
{
@@ -97,6 +95,11 @@ namespace osu.Game.Overlays.Direct
},
}
});
+
+ var downloadRequest = beatmaps.GetExistingDownload(SetInfo);
+
+ if (downloadRequest != null)
+ attachDownload(downloadRequest);
}
protected override bool OnHover(InputState state)
@@ -115,23 +118,8 @@ namespace osu.Game.Overlays.Direct
base.OnHoverLost(state);
}
- // this should eventually be moved to a more central place, like BeatmapManager.
- private DownloadBeatmapSetRequest downloadRequest;
-
protected void StartDownload()
{
- if (api == null) return;
-
- // we already have an active download running.
- if (downloadRequest != null)
- {
- content.MoveToX(-5, 50, Easing.OutSine).Then()
- .MoveToX(5, 100, Easing.InOutSine).Then()
- .MoveToX(-5, 100, Easing.InOutSine).Then()
- .MoveToX(0, 50, Easing.InSine).Then();
- return;
- }
-
if (!api.LocalUser.Value.IsSupporter)
{
notifications.Post(new SimpleNotification
@@ -142,72 +130,43 @@ namespace osu.Game.Overlays.Direct
return;
}
+ if (beatmaps.GetExistingDownload(SetInfo) != null)
+ {
+ // we already have an active download running.
+ content.MoveToX(-5, 50, Easing.OutSine).Then()
+ .MoveToX(5, 100, Easing.InOutSine).Then()
+ .MoveToX(-5, 100, Easing.InOutSine).Then()
+ .MoveToX(0, 50, Easing.InSine).Then();
+
+ return;
+ }
+
+ var request = beatmaps.Download(SetInfo);
+
+ attachDownload(request);
+ }
+
+ private void attachDownload(DownloadBeatmapSetRequest request)
+ {
progressBar.FadeIn(400, Easing.OutQuint);
progressBar.ResizeHeightTo(4, 400, Easing.OutQuint);
progressBar.Current.Value = 0;
- ProgressNotification downloadNotification = new ProgressNotification
- {
- Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}",
- };
-
- downloadRequest = new DownloadBeatmapSetRequest(SetInfo);
- downloadRequest.Failure += e =>
+ request.Failure += e =>
{
progressBar.Current.Value = 0;
progressBar.FadeOut(500);
- downloadNotification.State = ProgressNotificationState.Completed;
Logger.Error(e, "Failed to get beatmap download information");
-
- downloadRequest = null;
};
- downloadRequest.Progress += (current, total) =>
- {
- float progress = (float)current / total;
+ request.DownloadProgressed += progress => progressBar.Current.Value = progress;
- progressBar.Current.Value = progress;
-
- downloadNotification.State = ProgressNotificationState.Active;
- downloadNotification.Progress = progress;
- };
-
- downloadRequest.Success += data =>
+ request.Success += data =>
{
progressBar.Current.Value = 1;
progressBar.FadeOut(500);
-
- downloadNotification.State = ProgressNotificationState.Completed;
-
- using (var stream = new MemoryStream(data))
- using (var archive = new OszArchiveReader(stream))
- beatmaps.Import(archive);
};
-
- downloadNotification.CancelRequested += () =>
- {
- downloadRequest.Cancel();
- downloadRequest = null;
- return true;
- };
-
- notifications.Post(downloadNotification);
-
- // don't run in the main api queue as this is a long-running task.
- Task.Run(() => downloadRequest.Perform(api));
- }
-
- public class DownloadBeatmapSetRequest : APIDownloadRequest
- {
- private readonly BeatmapSetInfo beatmapSet;
-
- public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet)
- {
- this.beatmapSet = beatmapSet;
- }
-
- protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download";
}
protected override void LoadComplete()
diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs
index f734e43826..9c07e1087f 100644
--- a/osu.Game/Overlays/DirectOverlay.cs
+++ b/osu.Game/Overlays/DirectOverlay.cs
@@ -27,6 +27,7 @@ namespace osu.Game.Overlays
private APIAccess api;
private RulesetStore rulesets;
+ private BeatmapManager beatmaps;
private readonly FillFlowContainer resultCountsContainer;
private readonly OsuSpriteText resultCountsText;
@@ -46,9 +47,26 @@ namespace osu.Game.Overlays
set
{
if (beatmapSets?.Equals(value) ?? false) return;
+
beatmapSets = value;
- recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
+ if (beatmapSets == null) return;
+
+ var artists = new List();
+ var songs = new List();
+ var tags = new List();
+ foreach (var s in beatmapSets)
+ {
+ artists.Add(s.Metadata.Artist);
+ songs.Add(s.Metadata.Title);
+ tags.AddRange(s.Metadata.Tags.Split(' '));
+ }
+
+ ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
+
+ if (beatmapSets.Any() && panels == null)
+ // real use case? currently only seems to be for test case
+ recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
}
}
@@ -147,6 +165,8 @@ namespace osu.Game.Overlays
{
this.api = api;
this.rulesets = rulesets;
+ this.beatmaps = beatmaps;
+
resultCountsContainer.Colour = colours.Yellow;
beatmaps.BeatmapSetAdded += setAdded;
@@ -156,6 +176,7 @@ namespace osu.Game.Overlays
{
// if a new map was imported, we should remove it from search results (download completed etc.)
panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire();
+ BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID);
}
private void updateResultCounts()
@@ -237,20 +258,11 @@ namespace osu.Game.Overlays
getSetsRequest.Success += r =>
{
- BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets));
- if (BeatmapSets == null) return;
+ BeatmapSets = r?.
+ Select(response => response.ToBeatmapSet(rulesets)).
+ Where(b => beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null);
- var artists = new List();
- var songs = new List();
- var tags = new List();
- foreach (var s in BeatmapSets)
- {
- artists.Add(s.Metadata.Artist);
- songs.Add(s.Metadata.Title);
- tags.AddRange(s.Metadata.Tags.Split(' '));
- }
-
- ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
+ recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
};
api.Queue(getSetsRequest);
diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs
index 0a06439c3e..64d0d628f0 100644
--- a/osu.Game/Overlays/MusicController.cs
+++ b/osu.Game/Overlays/MusicController.cs
@@ -302,8 +302,8 @@ namespace osu.Game.Overlays
else
{
//figure out the best direction based on order in playlist.
- var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo.ID).Count();
- var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo.ID).Count();
+ var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count();
+ var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count();
direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
}
diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs
index 7af7363dda..b39c8ab7cf 100644
--- a/osu.Game/Overlays/Settings/SidebarButton.cs
+++ b/osu.Game/Overlays/Settings/SidebarButton.cs
@@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Settings
backgroundBox = new Box
{
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = OsuColour.Gray(60),
Alpha = 0,
},
diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs
index f2df2721d3..cb17216679 100644
--- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs
+++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs
@@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(80).Opacity(180),
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Alpha = 0,
},
Flow = new FillFlowContainer
diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
index c530e8d7ff..28ecf6ad03 100644
--- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
+++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150).Opacity(180),
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Depth = 2,
Alpha = 0,
});
diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs
index f54267af29..7b0034863e 100644
--- a/osu.Game/Rulesets/Mods/Mod.cs
+++ b/osu.Game/Rulesets/Mods/Mod.cs
@@ -16,6 +16,11 @@ namespace osu.Game.Rulesets.Mods
///
public abstract string Name { get; }
+ ///
+ /// The shortened name of this mod.
+ ///
+ public abstract string ShortenedName { get; }
+
///
/// The icon of this mod.
///
diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs
index ca120e446e..2b10d098f3 100644
--- a/osu.Game/Rulesets/Mods/ModAutoplay.cs
+++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs
@@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mods
public class ModAutoplay : Mod
{
public override string Name => "Autoplay";
+ public override string ShortenedName => "AT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto;
public override string Description => "Watch a perfect automated play through the song";
public override double ScoreMultiplier => 0;
diff --git a/osu.Game/Rulesets/Mods/ModCinema.cs b/osu.Game/Rulesets/Mods/ModCinema.cs
index 332bd2c5ac..581fbc5e3a 100644
--- a/osu.Game/Rulesets/Mods/ModCinema.cs
+++ b/osu.Game/Rulesets/Mods/ModCinema.cs
@@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public class ModCinema : ModAutoplay
{
public override string Name => "Cinema";
+ public override string ShortenedName => "CN";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema;
}
}
\ No newline at end of file
diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs
index 3e878d7104..cbad224316 100644
--- a/osu.Game/Rulesets/Mods/ModDaycore.cs
+++ b/osu.Game/Rulesets/Mods/ModDaycore.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModDaycore : ModHalfTime
{
public override string Name => "Daycore";
+ public override string ShortenedName => "DC";
public override FontAwesome Icon => FontAwesome.fa_question;
public override string Description => "whoaaaaa";
diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs
index 1aab56a9fc..d8aa5ea1d2 100644
--- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs
+++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public class ModDoubleTime : Mod, IApplicableToClock
{
public override string Name => "Double Time";
+ public override string ShortenedName => "DT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_doubletime;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Zoooooooooom";
diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs
index 075a62b0d7..aaf083fd9e 100644
--- a/osu.Game/Rulesets/Mods/ModEasy.cs
+++ b/osu.Game/Rulesets/Mods/ModEasy.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModEasy : Mod, IApplicableToDifficulty
{
public override string Name => "Easy";
+ public override string ShortenedName => "EZ";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_easy;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required.";
diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs
index b5ad859172..b7499e624a 100644
--- a/osu.Game/Rulesets/Mods/ModFlashlight.cs
+++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs
@@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModFlashlight : Mod
{
public override string Name => "Flashlight";
+ public override string ShortenedName => "FL";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_flashlight;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Restricted view area.";
diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs
index 14aede0809..a9e49bb4b0 100644
--- a/osu.Game/Rulesets/Mods/ModHalfTime.cs
+++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHalfTime : Mod, IApplicableToClock
{
public override string Name => "Half Time";
+ public override string ShortenedName => "HT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_halftime;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "Less zoom";
diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs
index f33f46a207..36d82362e3 100644
--- a/osu.Game/Rulesets/Mods/ModHardRock.cs
+++ b/osu.Game/Rulesets/Mods/ModHardRock.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHardRock : Mod, IApplicableToDifficulty
{
public override string Name => "Hard Rock";
+ public override string ShortenedName => "HR";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hardrock;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Everything just got a bit harder...";
diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs
index 89b9b3b62d..25f6ad024d 100644
--- a/osu.Game/Rulesets/Mods/ModHidden.cs
+++ b/osu.Game/Rulesets/Mods/ModHidden.cs
@@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHidden : Mod
{
public override string Name => "Hidden";
+ public override string ShortenedName => "HD";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override ModType Type => ModType.DifficultyIncrease;
public override bool Ranked => true;
diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs
index d04643fb8b..5cefd89023 100644
--- a/osu.Game/Rulesets/Mods/ModNightcore.cs
+++ b/osu.Game/Rulesets/Mods/ModNightcore.cs
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModNightcore : ModDoubleTime
{
public override string Name => "Nightcore";
+ public override string ShortenedName => "NC";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nightcore;
public override string Description => "uguuuuuuuu";
diff --git a/osu.Game/Rulesets/Mods/ModNoFail.cs b/osu.Game/Rulesets/Mods/ModNoFail.cs
index d41c4e3956..3a3878d77e 100644
--- a/osu.Game/Rulesets/Mods/ModNoFail.cs
+++ b/osu.Game/Rulesets/Mods/ModNoFail.cs
@@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModNoFail : Mod
{
public override string Name => "NoFail";
+ public override string ShortenedName => "NF";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "You can't fail, no matter what.";
diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs
index 35217c8305..082370ea5d 100644
--- a/osu.Game/Rulesets/Mods/ModPerfect.cs
+++ b/osu.Game/Rulesets/Mods/ModPerfect.cs
@@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModPerfect : ModSuddenDeath
{
public override string Name => "Perfect";
+ public override string ShortenedName => "PF";
public override string Description => "SS or quit.";
}
}
\ No newline at end of file
diff --git a/osu.Game/Rulesets/Mods/ModRelax.cs b/osu.Game/Rulesets/Mods/ModRelax.cs
index 5491f8fc58..a3f38e4ff6 100644
--- a/osu.Game/Rulesets/Mods/ModRelax.cs
+++ b/osu.Game/Rulesets/Mods/ModRelax.cs
@@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModRelax : Mod
{
public override string Name => "Relax";
+ public override string ShortenedName => "RX";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax;
public override double ScoreMultiplier => 0;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) };
diff --git a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
index 2bf0278046..999cb40f89 100644
--- a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
+++ b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
@@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModSuddenDeath : Mod
{
public override string Name => "Sudden Death";
+ public override string ShortenedName => "SD";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_suddendeath;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Miss a note and fail.";
diff --git a/osu.Game/Rulesets/Mods/MultiMod.cs b/osu.Game/Rulesets/Mods/MultiMod.cs
index c5fac250d0..c40d107bda 100644
--- a/osu.Game/Rulesets/Mods/MultiMod.cs
+++ b/osu.Game/Rulesets/Mods/MultiMod.cs
@@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods
public class MultiMod : Mod
{
public override string Name => string.Empty;
+ public override string ShortenedName => string.Empty;
public override string Description => string.Empty;
public override double ScoreMultiplier => 0.0;
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index 3fba168216..369ea76028 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -12,10 +12,11 @@ using osu.Game.Rulesets.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Audio;
using System.Linq;
+using osu.Game.Graphics;
namespace osu.Game.Rulesets.Objects.Drawables
{
- public abstract class DrawableHitObject : Container
+ public abstract class DrawableHitObject : Container, IHasAccentColour
{
public readonly HitObject HitObject;
diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs
index c54aeb7852..33621662af 100644
--- a/osu.Game/Rulesets/Ruleset.cs
+++ b/osu.Game/Rulesets/Ruleset.cs
@@ -1,15 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Beatmaps;
-using osu.Game.Graphics;
-using osu.Game.Rulesets.Mods;
-using osu.Game.Rulesets.UI;
+using System;
using System.Collections.Generic;
+using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
-using osu.Game.Rulesets.Scoring;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics;
using osu.Game.Overlays.Settings;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets
{
@@ -19,9 +21,18 @@ namespace osu.Game.Rulesets
public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { };
+ public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast()
+ // Get all mod types as an IEnumerable
+ .SelectMany(GetModsFor)
+ // Confine all mods of each mod type into a single IEnumerable
+ .Where(mod => mod != null)
+ // Filter out all null mods
+ .SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod });
+ // Resolve MultiMods as their .Mods property
+
public abstract IEnumerable GetModsFor(ModType type);
- public abstract Mod GetAutoplayMod();
+ public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay);
protected Ruleset(RulesetInfo rulesetInfo)
{
diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs
index 6169bb7380..ff4632a9c2 100644
--- a/osu.Game/Rulesets/Scoring/Score.cs
+++ b/osu.Game/Rulesets/Scoring/Score.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Users;
@@ -15,70 +14,30 @@ namespace osu.Game.Rulesets.Scoring
{
public ScoreRank Rank { get; set; }
- [JsonProperty(@"score")]
public double TotalScore { get; set; }
public double Accuracy { get; set; }
public double Health { get; set; } = 1;
- [JsonProperty(@"max_combo")]
public int MaxCombo { get; set; }
public int Combo { get; set; }
- [JsonProperty(@"mods")]
- protected string[] ModStrings { get; set; } //todo: parse to Mod objects
-
public RulesetInfo Ruleset { get; set; }
public Mod[] Mods { get; set; }
- [JsonProperty(@"user")]
public User User;
- [JsonProperty(@"replay_data")]
public Replay Replay;
public BeatmapInfo Beatmap;
- [JsonProperty(@"score_id")]
public long OnlineScoreID;
- [JsonProperty(@"created_at")]
public DateTimeOffset Date;
- [JsonProperty(@"statistics")]
- private Dictionary jsonStats
- {
- set
- {
- foreach (var kvp in value)
- {
- string key = kvp.Key;
- switch (key)
- {
- case @"count_300":
- key = @"300";
- break;
- case @"count_100":
- key = @"100";
- break;
- case @"count_50":
- key = @"50";
- break;
- case @"count_miss":
- key = @"x";
- break;
- default:
- continue;
- }
-
- Statistics.Add(key, kvp.Value);
- }
- }
- }
-
public Dictionary Statistics = new Dictionary();
}
}
diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs
index 986d8c92dc..47a39d4644 100644
--- a/osu.Game/Rulesets/UI/ModIcon.cs
+++ b/osu.Game/Rulesets/UI/ModIcon.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI
private readonly SpriteIcon modIcon;
private readonly SpriteIcon background;
- private const float icon_size = 80;
+ private const float background_size = 80;
public FontAwesome Icon
{
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.UI
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
- Size = new Vector2(icon_size),
+ Size = new Vector2(background_size),
Icon = FontAwesome.fa_osu_mod_bg,
Shadow = true,
},
@@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Colour = OsuColour.Gray(84),
- Size = new Vector2(icon_size - 35),
+ Size = new Vector2(background_size - 35),
Y = 25,
Icon = mod.Icon
},
diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs
index a7472f4dbc..34b079951d 100644
--- a/osu.Game/Rulesets/UI/RulesetContainer.cs
+++ b/osu.Game/Rulesets/UI/RulesetContainer.cs
@@ -75,9 +75,6 @@ namespace osu.Game.Rulesets.UI
internal RulesetContainer(Ruleset ruleset)
{
Ruleset = ruleset;
-
- KeyBindingInputManager = CreateInputManager();
- KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
}
///
@@ -190,6 +187,9 @@ namespace osu.Game.Rulesets.UI
// Post-process the beatmap
processor.PostProcess(Beatmap);
+ KeyBindingInputManager = CreateInputManager();
+ KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
+
// Add mods, should always be the last thing applied to give full control to mods
applyMods(Mods);
}
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 9f33d624e2..be9098e3be 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -8,6 +8,11 @@ using osu.Framework.Screens;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Select;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Game.Graphics;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Screens.Edit.Menus;
namespace osu.Game.Screens.Edit
{
@@ -17,6 +22,175 @@ namespace osu.Game.Screens.Edit
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4");
+ internal override bool ShowOverlays => false;
+
+ public Editor()
+ {
+ Add(new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 40,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.FromHex("111")
+ },
+ new EditorMenuBar
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ X = 100,
+ Items = new[]
+ {
+ new EditorMenuBarItem("File")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Clear all notes"),
+ new EditorMenuItem("Open difficulty..."),
+ new EditorMenuItem("Save"),
+ new EditorMenuItem("Create new difficulty..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Revert to saved"),
+ new EditorMenuItem("Revert to saved (full"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Test beatmap"),
+ new EditorMenuItem("Open AiMod"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Upload Beatmap..."),
+ new EditorMenuItem("Export package"),
+ new EditorMenuItem("Export map package"),
+ new EditorMenuItem("Import from..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Open song folder"),
+ new EditorMenuItem("Open .osu in Notepad"),
+ new EditorMenuItem("Open .osb in Notepad"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Exit", MenuItemType.Standard, Exit)
+ }
+ },
+ new EditorMenuBarItem("Edit")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Undo"),
+ new EditorMenuItem("Redo"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Cut"),
+ new EditorMenuItem("Copy"),
+ new EditorMenuItem("Paste"),
+ new EditorMenuItem("Delete"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Select all"),
+ new EditorMenuItem("Clone"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Reverse selection"),
+ new EditorMenuItem("Flip horizontally"),
+ new EditorMenuItem("Flip vertically"),
+ new EditorMenuItem("Rotate 90deg clockwise"),
+ new EditorMenuItem("Rotate 90deg anticlockwise"),
+ new EditorMenuItem("Rotate by..."),
+ new EditorMenuItem("Scale by..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Reset selected objects' samples"),
+ new EditorMenuItem("Reset all samples", MenuItemType.Destructive),
+ new EditorMenuItem("Reset combo colours", MenuItemType.Destructive),
+ new EditorMenuItem("Reset breaks", MenuItemType.Destructive),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Nudge backward"),
+ new EditorMenuItem("Nudge forward")
+ }
+ },
+ new EditorMenuBarItem("View")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Compose"),
+ new EditorMenuItem("Design"),
+ new EditorMenuItem("Timing"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Song setup..."),
+ new EditorMenuItem("Timing setup..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Volume"),
+ new EditorMenuItem("Grid level"),
+ new EditorMenuItem("Show video"),
+ new EditorMenuItem("Show sample name"),
+ new EditorMenuItem("Snaking sliders"),
+ new EditorMenuItem("Hit animations"),
+ new EditorMenuItem("Follow points"),
+ new EditorMenuItem("Stacking")
+ }
+ },
+ new EditorMenuBarItem("Compose")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Snap divisor"),
+ new EditorMenuItem("Audio rate"),
+ new EditorMenuItem("Grid snapping"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Create polygon cricles..."),
+ new EditorMenuItem("Convert slider to stream"),
+ new EditorMenuItem("Enable live mapping mode"),
+ new EditorMenuItem("Sample import")
+ }
+ },
+ new EditorMenuBarItem("Design")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Move all elements in time...")
+ }
+ },
+ new EditorMenuBarItem("Timing")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Time signature"),
+ new EditorMenuItem("Metronome clicks"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Add timing section"),
+ new EditorMenuItem("Add inheriting section"),
+ new EditorMenuItem("Reset current section"),
+ new EditorMenuItem("Delete timing section"),
+ new EditorMenuItem("Resnap current section"),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Timing setup..."),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Resnap all notes", MenuItemType.Destructive),
+ new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive),
+ new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive),
+ new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive),
+ new EditorMenuItemSpacer(),
+ new EditorMenuItem("Set current position as preview point")
+ }
+ },
+ new EditorMenuBarItem("Web")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("This Beatmap's information page"),
+ new EditorMenuItem("This Beatmap's thread"),
+ new EditorMenuItem("Quick reply")
+ }
+ },
+ new EditorMenuBarItem("Help")
+ {
+ Items = new[]
+ {
+ new EditorMenuItem("Show in-game help"),
+ new EditorMenuItem("View FAQ")
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
protected override void OnResuming(Screen last)
{
Beatmap.Value.Track?.Stop();
diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs
new file mode 100644
index 0000000000..bb349b1531
--- /dev/null
+++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs
@@ -0,0 +1,122 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// 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.Shapes;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Input;
+using osu.Game.Graphics;
+using osu.Game.Graphics.UserInterface;
+using OpenTK;
+using OpenTK.Graphics;
+
+namespace osu.Game.Screens.Edit.Menus
+{
+ public class EditorMenuBar : OsuMenu
+ {
+ public EditorMenuBar()
+ : base(Direction.Horizontal, true)
+ {
+ ItemsContainer.Padding = new MarginPadding(0);
+ BackgroundColour = Color4.Transparent;
+ }
+
+ protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
+
+ protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorBarMenuItem(item);
+
+ private class DrawableEditorBarMenuItem : DrawableOsuMenuItem
+ {
+ private Color4 openedForegroundColour;
+ private Color4 openedBackgroundColour;
+
+ public DrawableEditorBarMenuItem(MenuItem item)
+ : base(item)
+ {
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ ForegroundColour = ForegroundColourHover = colours.BlueLight;
+ BackgroundColour = BackgroundColourHover = Color4.Transparent;
+ openedForegroundColour = Color4.White;
+ openedBackgroundColour = colours.Gray3;
+ }
+
+ protected override void UpdateBackgroundColour()
+ {
+ if (State == MenuItemState.Selected)
+ Background.FadeColour(openedBackgroundColour);
+ else
+ base.UpdateBackgroundColour();
+ }
+
+ protected override void UpdateForegroundColour()
+ {
+ if (State == MenuItemState.Selected)
+ Foreground.FadeColour(openedForegroundColour);
+ else
+ base.UpdateForegroundColour();
+ }
+
+ protected override Drawable CreateBackground() => new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ Child = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Height = 2,
+ Masking = true,
+ CornerRadius = 4,
+ Child = new Box { RelativeSizeAxes = Axes.Both }
+ }
+ };
+ }
+
+ private class SubMenu : OsuMenu
+ {
+ public SubMenu()
+ : base(Direction.Vertical)
+ {
+ OriginPosition = new Vector2(5, 1);
+ ItemsContainer.Padding = new MarginPadding { Top = 5, Bottom = 5 };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ BackgroundColour = colours.Gray3;
+ }
+
+ protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
+
+ protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableSubMenuItem(item);
+
+ private class DrawableSubMenuItem : DrawableOsuMenuItem
+ {
+ public DrawableSubMenuItem(MenuItem item)
+ : base(item)
+ {
+ }
+
+ protected override bool OnHover(InputState state)
+ {
+ if (Item is EditorMenuItemSpacer)
+ return true;
+ return base.OnHover(state);
+ }
+
+ protected override bool OnClick(InputState state)
+ {
+ if (Item is EditorMenuItemSpacer)
+ return true;
+ return base.OnClick(state);
+ }
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs
new file mode 100644
index 0000000000..201bc6e5c3
--- /dev/null
+++ b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs
@@ -0,0 +1,15 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics.UserInterface;
+
+namespace osu.Game.Screens.Edit.Menus
+{
+ public class EditorMenuBarItem : MenuItem
+ {
+ public EditorMenuBarItem(string text)
+ : base(text)
+ {
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs
new file mode 100644
index 0000000000..c7e36522cf
--- /dev/null
+++ b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs
@@ -0,0 +1,23 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using osu.Game.Graphics.UserInterface;
+
+namespace osu.Game.Screens.Edit.Menus
+{
+ public class EditorMenuItem : OsuMenuItem
+ {
+ private const int min_text_length = 40;
+
+ public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard)
+ : base(text.PadRight(min_text_length), type)
+ {
+ }
+
+ public EditorMenuItem(string text, MenuItemType type, Action action)
+ : base(text.PadRight(min_text_length), type, action)
+ {
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs
new file mode 100644
index 0000000000..5060165ef7
--- /dev/null
+++ b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs
@@ -0,0 +1,13 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+namespace osu.Game.Screens.Edit.Menus
+{
+ public class EditorMenuItemSpacer : EditorMenuItem
+ {
+ public EditorMenuItemSpacer()
+ : base(" ")
+ {
+ }
+ }
+}
diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs
index aca169c3dc..6952f66f95 100644
--- a/osu.Game/Screens/Menu/Button.cs
+++ b/osu.Game/Screens/Menu/Button.cs
@@ -83,7 +83,7 @@ namespace osu.Game.Screens.Menu
{
EdgeSmoothness = new Vector2(1.5f, 0),
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs
index a0cf6eec66..3aeef4bbc9 100644
--- a/osu.Game/Screens/Menu/Intro.cs
+++ b/osu.Game/Screens/Menu/Intro.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Screens.Menu
{
Alpha = 0,
Triangles = false,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Interactive = false,
Colour = Color4.DarkGray,
Ripple = false
diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs
index 2de4c1b21f..bc94f88866 100644
--- a/osu.Game/Screens/Menu/LogoVisualisation.cs
+++ b/osu.Game/Screens/Menu/LogoVisualisation.cs
@@ -73,7 +73,7 @@ namespace osu.Game.Screens.Menu
{
texture = Texture.WhitePixel;
AccentColour = new Color4(1, 1, 1, 0.2f);
- BlendingMode = BlendingMode.Additive;
+ Blending = BlendingMode.Additive;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs
index 49c777f09a..9317780eac 100644
--- a/osu.Game/Screens/Menu/MenuSideFlashes.cs
+++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs
@@ -50,7 +50,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
},
rightBox = new Box
{
@@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
}
};
}
diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs
index 64c28816d8..55c25d4c54 100644
--- a/osu.Game/Screens/Menu/OsuLogo.cs
+++ b/osu.Game/Screens/Menu/OsuLogo.cs
@@ -108,7 +108,7 @@ namespace osu.Game.Screens.Menu
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Alpha = 0
}
}
@@ -169,7 +169,7 @@ namespace osu.Game.Screens.Menu
flashLayer = new Box
{
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs
index 0f6c5984c4..d21be71785 100644
--- a/osu.Game/Screens/Play/KeyCounterCollection.cs
+++ b/osu.Game/Screens/Play/KeyCounterCollection.cs
@@ -28,6 +28,8 @@ namespace osu.Game.Screens.Play
public override void Add(KeyCounter key)
{
+ if (key == null) throw new ArgumentNullException(nameof(key));
+
base.Add(key);
key.IsCounting = IsCounting;
key.FadeTime = FadeTime;
diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs
index 408dbd8f16..fcf87de655 100644
--- a/osu.Game/Screens/ScreenWhiteBox.cs
+++ b/osu.Game/Screens/ScreenWhiteBox.cs
@@ -100,7 +100,7 @@ namespace osu.Game.Screens
Colour = getColourFor(GetType()),
Alpha = 0.2f,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
},
textContainer = new FillFlowContainer
{
diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs
index 47d25585ad..a676516300 100644
--- a/osu.Game/Screens/Select/BeatmapDetailArea.cs
+++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@@ -10,6 +11,8 @@ namespace osu.Game.Screens.Select
{
public class BeatmapDetailArea : Container
{
+ private const float details_padding = 10;
+
private readonly Container content;
protected override Container Content => content;
@@ -66,9 +69,8 @@ namespace osu.Game.Screens.Select
Details = new BeatmapDetails
{
RelativeSizeAxes = Axes.X,
- Masking = true,
- Height = 352,
Alpha = 0,
+ Margin = new MarginPadding { Top = details_padding },
},
Leaderboard = new Leaderboard
{
@@ -76,5 +78,12 @@ namespace osu.Game.Screens.Select
}
});
}
+
+ protected override void UpdateAfterChildren()
+ {
+ base.UpdateAfterChildren();
+
+ Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450);
+ }
}
}
diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs
index a5486efa96..a98362e89c 100644
--- a/osu.Game/Screens/Select/BeatmapDetails.cs
+++ b/osu.Game/Screens/Select/BeatmapDetails.cs
@@ -9,71 +9,189 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
-using System.Globalization;
using System.Linq;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Framework.Threading;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Game.Screens.Select.Details;
using osu.Game.Beatmaps;
namespace osu.Game.Screens.Select
{
public class BeatmapDetails : Container
{
- private readonly MetadataSegment description;
- private readonly MetadataSegment source;
- private readonly MetadataSegment tags;
+ private const float spacing = 10;
+ private const float transition_duration = 250;
- private readonly DifficultyRow circleSize;
- private readonly DifficultyRow drainRate;
- private readonly DifficultyRow overallDifficulty;
- private readonly DifficultyRow approachRate;
- private readonly DifficultyRow stars;
+ private readonly FillFlowContainer top, statsFlow;
+ private readonly AdvancedStats advanced;
+ private readonly DetailBox ratingsContainer;
+ private readonly UserRatings ratings;
+ private readonly ScrollContainer metadataScroll;
+ private readonly MetadataSection description, source, tags;
+ private readonly Container failRetryContainer;
+ private readonly FailRetryGraph failRetryGraph;
+ private readonly DimmedLoadingAnimation loading;
- private readonly Container ratingsContainer;
- private readonly Bar ratingsBar;
- private readonly OsuSpriteText negativeRatings;
- private readonly OsuSpriteText positiveRatings;
- private readonly BarGraph ratingsGraph;
-
- private readonly FillFlowContainer retryFailContainer;
- private readonly BarGraph retryGraph;
- private readonly BarGraph failGraph;
+ private APIAccess api;
private ScheduledDelegate pendingBeatmapSwitch;
- private BeatmapInfo beatmap;
+ private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get { return beatmap; }
-
set
{
- if (beatmap == value) return;
-
+ if (value == beatmap) return;
beatmap = value;
pendingBeatmapSwitch?.Cancel();
- pendingBeatmapSwitch = Schedule(updateStats);
+ pendingBeatmapSwitch = Schedule(updateStatistics);
}
}
- private void updateStats()
+ public BeatmapDetails()
{
- if (beatmap == null) return;
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black.Opacity(0.5f),
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Horizontal = spacing },
+ Children = new Drawable[]
+ {
+ top = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Horizontal,
+ Children = new Drawable[]
+ {
+ statsFlow = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Width = 0.5f,
+ Spacing = new Vector2(spacing),
+ Padding = new MarginPadding { Right = spacing / 2 },
+ Children = new[]
+ {
+ new DetailBox
+ {
+ Child = advanced = new AdvancedStats
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Padding = new MarginPadding { Horizontal = spacing, Top = spacing * 2, Bottom = spacing },
+ },
+ },
+ ratingsContainer = new DetailBox
+ {
+ Child = ratings = new UserRatings
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 134,
+ Padding = new MarginPadding { Horizontal = spacing, Top = spacing },
+ },
+ },
+ },
+ },
+ metadataScroll = new ScrollContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ Width = 0.5f,
+ ScrollbarVisible = false,
+ Padding = new MarginPadding { Left = spacing / 2 },
+ Child = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ LayoutDuration = transition_duration,
+ Spacing = new Vector2(spacing * 2),
+ Margin = new MarginPadding { Top = spacing * 2 },
+ Children = new[]
+ {
+ description = new MetadataSection("Description")
+ {
+ TextColour = Color4.White.Opacity(0.75f),
+ },
+ source = new MetadataSection("Source")
+ {
+ TextColour = Color4.White.Opacity(0.75f),
+ },
+ tags = new MetadataSection("Tags"),
+ },
+ },
+ },
+ },
+ },
+ failRetryContainer = new Container
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ RelativeSizeAxes = Axes.X,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = "Points of Failure",
+ Font = @"Exo2.0-Bold",
+ TextSize = 14,
+ },
+ failRetryGraph = new FailRetryGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Top = 14 + spacing / 2 },
+ },
+ },
+ },
+ },
+ },
+ loading = new DimmedLoadingAnimation
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ };
+ }
- description.Text = beatmap.Version;
- source.Text = beatmap.Metadata.Source;
- tags.Text = beatmap.Metadata.Tags;
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours, APIAccess api)
+ {
+ this.api = api;
+ tags.TextColour = colours.Yellow;
+ }
- circleSize.Value = beatmap.Difficulty.CircleSize;
- drainRate.Value = beatmap.Difficulty.DrainRate;
- overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
- approachRate.Value = beatmap.Difficulty.ApproachRate;
- stars.Value = (float)beatmap.StarDifficulty;
+ protected override void UpdateAfterChildren()
+ {
+ base.UpdateAfterChildren();
- var requestedBeatmap = beatmap;
+ metadataScroll.Height = statsFlow.DrawHeight;
+ failRetryContainer.Height = DrawHeight - Padding.TotalVertical - (top.DrawHeight + spacing / 2);
+ }
+
+ private void updateStatistics()
+ {
+ if (Beatmap == null)
+ {
+ clearStats();
+ return;
+ }
+
+ ratingsContainer.FadeIn(transition_duration);
+ advanced.Beatmap = Beatmap;
+ description.Text = Beatmap.Version;
+ source.Text = Beatmap.Metadata.Source;
+ tags.Text = Beatmap.Metadata.Tags;
+
+ var requestedBeatmap = Beatmap;
if (requestedBeatmap.Metrics == null)
{
var lookup = new GetBeatmapDetailsRequest(requestedBeatmap);
@@ -84,413 +202,195 @@ namespace osu.Game.Screens.Select
return;
requestedBeatmap.Metrics = res;
- Schedule(() => updateMetrics(res));
+ Schedule(() => displayMetrics(res));
};
- lookup.Failure += e => Schedule(() => updateMetrics(null));
+ lookup.Failure += e => Schedule(() => displayMetrics(null));
api.Queue(lookup);
loading.Show();
}
- updateMetrics(requestedBeatmap.Metrics, false);
+ displayMetrics(requestedBeatmap.Metrics, false);
}
- ///
- /// Update displayed metrics.
- ///
- /// New metrics to overwrite the existing display. Can be null.
- /// Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates.
- private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true)
+ private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true)
{
- var hasRatings = metrics?.Ratings.Any() ?? false;
- var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any();
+ var hasRatings = metrics?.Ratings?.Any() ?? false;
+ var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics.Fails?.Any() ?? false);
- if (failOnMissing)
- loading.Hide();
+ if (failOnMissing) loading.Hide();
if (hasRatings)
{
- var ratings = metrics.Ratings.ToList();
- ratingsContainer.Show();
-
- negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
- positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
- ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
-
- ratingsGraph.Values = ratings.Select(rating => (float)rating);
-
- ratingsContainer.FadeColour(Color4.White, 500, Easing.Out);
+ ratings.Metrics = metrics;
+ ratings.FadeIn(transition_duration);
}
else if (failOnMissing)
- ratingsGraph.Values = new float[10];
+ {
+ ratings.Metrics = new BeatmapMetrics
+ {
+ Ratings = new int[10],
+ };
+ }
else
- ratingsContainer.FadeColour(Color4.Gray, 500, Easing.Out);
+ {
+ ratings.FadeTo(0.25f, transition_duration);
+ }
if (hasRetriesFails)
{
- var retries = metrics.Retries;
- var fails = metrics.Fails;
- retryFailContainer.Show();
-
- float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
- failGraph.MaxValue = maxValue;
- retryGraph.MaxValue = maxValue;
-
- failGraph.Values = fails.Select(fail => (float)fail);
- retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
-
- retryFailContainer.FadeColour(Color4.White, 500, Easing.Out);
+ failRetryGraph.Metrics = metrics;
+ failRetryContainer.FadeIn(transition_duration);
}
else if (failOnMissing)
{
- failGraph.Values = new float[100];
- retryGraph.Values = new float[100];
+ failRetryGraph.Metrics = new BeatmapMetrics
+ {
+ Fails = new int[100],
+ Retries = new int[100],
+ };
}
else
- retryFailContainer.FadeColour(Color4.Gray, 500, Easing.Out);
+ {
+ failRetryContainer.FadeTo(0.25f, transition_duration);
+ }
}
- public BeatmapDetails()
+ private void clearStats()
{
- Children = new Drawable[]
+ description.Text = null;
+ source.Text = null;
+ tags.Text = null;
+ advanced.Beatmap = new BeatmapInfo
{
- new Box
+ StarDifficulty = 0,
+ Difficulty = new BeatmapDifficulty
{
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black,
- Alpha = 0.5f,
+ CircleSize = 0,
+ DrainRate = 0,
+ OverallDifficulty = 0,
+ ApproachRate = 0,
},
- new FillFlowContainer
- {
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Width = 0.4f,
- Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
- Children = new[]
- {
- description = new MetadataSegment("Description"),
- source = new MetadataSegment("Source"),
- tags = new MetadataSegment("Tags")
- },
- },
- new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Width = 0.6f,
- Direction = FillDirection.Vertical,
- Spacing = new Vector2(0, 15),
- Padding = new MarginPadding(10) { Top = 0 },
- Children = new Drawable[]
- {
- new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black,
- Alpha = 0.5f,
- },
- new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
- Spacing = new Vector2(0, 5),
- Padding = new MarginPadding(10),
- Children = new[]
- {
- circleSize = new DifficultyRow("Circle Size", 7),
- drainRate = new DifficultyRow("HP Drain"),
- overallDifficulty = new DifficultyRow("Accuracy"),
- approachRate = new DifficultyRow("Approach Rate"),
- stars = new DifficultyRow("Star Difficulty"),
- },
- },
- },
- },
- ratingsContainer = new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Alpha = 0,
- AlwaysPresent = true,
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black,
- Alpha = 0.5f,
- },
- new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
- Padding = new MarginPadding
- {
- Top = 25,
- Left = 15,
- Right = 15,
- },
- Children = new Drawable[]
- {
- new OsuSpriteText
- {
- Text = "User Rating",
- Font = @"Exo2.0-Medium",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- },
- ratingsBar = new Bar
- {
- RelativeSizeAxes = Axes.X,
- Height = 5,
- },
- new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Children = new[]
- {
- negativeRatings = new OsuSpriteText
- {
- Font = @"Exo2.0-Regular",
- Text = "0",
- },
- positiveRatings = new OsuSpriteText
- {
- Font = @"Exo2.0-Regular",
- Text = "0",
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- },
- },
- },
- new OsuSpriteText
- {
- Text = "Rating Spread",
- TextSize = 14,
- Font = @"Exo2.0-Regular",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- },
- ratingsGraph = new BarGraph
- {
- RelativeSizeAxes = Axes.X,
- Height = 50,
- },
- },
- },
- },
- },
- retryFailContainer = new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Alpha = 0,
- Children = new Drawable[]
- {
- new OsuSpriteText
- {
- Text = "Points of Failure",
- Font = @"Exo2.0-Regular",
- },
- new Container
- {
- RelativeSizeAxes = Axes.X,
- Size = new Vector2(1 / 0.6f, 50),
- Children = new[]
- {
- retryGraph = new BarGraph
- {
- RelativeSizeAxes = Axes.Both,
- },
- failGraph = new BarGraph
- {
- RelativeSizeAxes = Axes.Both,
- },
- },
- },
- }
- },
- },
- },
- loading = new LoadingAnimation()
};
+
+ loading.Hide();
+ ratingsContainer.FadeOut(transition_duration);
+ failRetryContainer.FadeOut(transition_duration);
}
- private APIAccess api;
- private readonly LoadingAnimation loading;
-
- [BackgroundDependencyLoader]
- private void load(OsuColour colour, APIAccess api)
+ private class DetailBox : Container
{
- this.api = api;
+ private readonly Container content;
+ protected override Container Content => content;
- description.AccentColour = colour.GrayB;
- source.AccentColour = colour.GrayB;
- tags.AccentColour = colour.YellowLight;
-
- stars.AccentColour = colour.Yellow;
-
- ratingsBar.BackgroundColour = colour.Green;
- ratingsBar.AccentColour = colour.YellowDark;
- ratingsGraph.Colour = colour.BlueDark;
-
- failGraph.Colour = colour.YellowDarker;
- retryGraph.Colour = colour.Yellow;
- }
-
- private class DifficultyRow : Container, IHasAccentColour
- {
- private readonly OsuSpriteText name;
- private readonly Bar bar;
- private readonly OsuSpriteText valueText;
-
- private readonly float maxValue;
-
- private float difficultyValue;
- public float Value
+ public DetailBox()
{
- get
- {
- return difficultyValue;
- }
- set
- {
- difficultyValue = value;
- bar.Length = value / maxValue;
- valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture);
- }
- }
-
- public Color4 AccentColour
- {
- get
- {
- return bar.AccentColour;
- }
- set
- {
- bar.AccentColour = value;
- }
- }
-
- public DifficultyRow(string difficultyName, float maxValue = 10)
- {
- this.maxValue = maxValue;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
- Children = new Drawable[]
+
+ InternalChildren = new Drawable[]
{
- name = new OsuSpriteText
+ new Box
{
- Font = @"Exo2.0-Regular",
- Text = difficultyName,
- },
- bar = new Bar
- {
- Origin = Anchor.CentreLeft,
- Anchor = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
- Size = new Vector2(1, 0.35f),
- Padding = new MarginPadding { Left = 100, Right = 25 },
+ Colour = Color4.Black.Opacity(0.5f),
},
- valueText = new OsuSpriteText
+ content = new Container
{
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- Font = @"Exo2.0-Regular",
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
},
};
}
-
- [BackgroundDependencyLoader]
- private void load(OsuColour colour)
- {
- name.Colour = colour.GrayB;
- bar.BackgroundColour = colour.Gray7;
- valueText.Colour = colour.GrayB;
- }
}
- private class MetadataSegment : Container, IHasAccentColour
+ private class MetadataSection : Container
{
- private readonly OsuSpriteText header;
- private readonly FillFlowContainer content;
+ private readonly TextFlowContainer textFlow;
public string Text
{
set
{
if (string.IsNullOrEmpty(value))
- Hide();
- else
{
- Show();
- if (header.Text == "Tags")
- content.ChildrenEnumerable = value.Split(' ').Select(text => new OsuSpriteText
- {
- Text = text,
- Font = "Exo2.0-Regular",
- });
- else
- content.Children = new[]
- {
- new OsuSpriteText
- {
- Text = value,
- Font = "Exo2.0-Regular",
- }
- };
+ this.FadeOut(transition_duration);
+ return;
}
+
+ this.FadeIn(transition_duration);
+ textFlow.Clear();
+ textFlow.AddText(value, s => s.TextSize = 14);
}
}
- public Color4 AccentColour
+ public Color4 TextColour
{
- get
- {
- return content.Colour;
- }
- set
- {
- content.Colour = value;
- }
+ get { return textFlow.Colour; }
+ set { textFlow.Colour = value; }
}
- public MetadataSegment(string headerText)
+ public MetadataSection(string title)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
- Margin = new MarginPadding { Top = 10 };
+
+ InternalChild = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Spacing = new Vector2(spacing / 2),
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Child = new OsuSpriteText
+ {
+ Text = title,
+ Font = @"Exo2.0-Bold",
+ TextSize = 14,
+ },
+ },
+ textFlow = new TextFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ },
+ },
+ };
+ }
+ }
+
+ private class DimmedLoadingAnimation : VisibilityContainer
+ {
+ private readonly LoadingAnimation loading;
+
+ public DimmedLoadingAnimation()
+ {
Children = new Drawable[]
{
- header = new OsuSpriteText
+ new Box
{
- Font = @"Exo2.0-Bold",
- Text = headerText,
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black.Opacity(0.5f),
},
- content = new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Full,
- Spacing = new Vector2(5, 0),
- Margin = new MarginPadding { Top = header.TextSize }
- }
+ loading = new LoadingAnimation(),
};
}
+
+ protected override void PopIn()
+ {
+ this.FadeIn(transition_duration, Easing.OutQuint);
+ loading.State = Visibility.Visible;
+ }
+
+ protected override void PopOut()
+ {
+ this.FadeOut(transition_duration, Easing.OutQuint);
+ loading.State = Visibility.Hidden;
+ }
}
}
}
diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs
new file mode 100644
index 0000000000..d92c8ed509
--- /dev/null
+++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs
@@ -0,0 +1,152 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using System;
+using osu.Game.Beatmaps;
+
+namespace osu.Game.Screens.Select.Details
+{
+ public class AdvancedStats : Container
+ {
+ private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty;
+
+ private BeatmapInfo beatmap;
+ public BeatmapInfo Beatmap
+ {
+ get { return beatmap; }
+ set
+ {
+ if (value == beatmap) return;
+ beatmap = value;
+
+ //mania specific
+ if ((Beatmap?.Ruleset?.ID ?? 0) == 3)
+ {
+ firstValue.Title = "Key Amount";
+ firstValue.Value = (int)Math.Round(Beatmap?.Difficulty?.CircleSize ?? 0);
+ }
+ else
+ {
+ firstValue.Title = "Circle Size";
+ firstValue.Value = Beatmap?.Difficulty?.CircleSize ?? 0;
+ }
+
+ hpDrain.Value = beatmap.Difficulty.DrainRate;
+ accuracy.Value = beatmap.Difficulty.OverallDifficulty;
+ approachRate.Value = beatmap.Difficulty.ApproachRate;
+ starDifficulty.Value = (float)beatmap.StarDifficulty;
+ }
+ }
+
+ public AdvancedStats()
+ {
+ Child = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Spacing = new Vector2(4f),
+ Children = new[]
+ {
+ firstValue = new StatisticRow(), //circle size/key amount
+ hpDrain = new StatisticRow { Title = "HP Drain" },
+ accuracy = new StatisticRow { Title = "Accuracy" },
+ approachRate = new StatisticRow { Title = "Approach Rate" },
+ starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
+ },
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ starDifficulty.AccentColour = colours.Yellow;
+ }
+
+ private class StatisticRow : Container, IHasAccentColour
+ {
+ private const float value_width = 25;
+ private const float name_width = 70;
+
+ private readonly float maxValue;
+ private readonly bool forceDecimalPlaces;
+ private readonly OsuSpriteText name, value;
+ private readonly Bar bar;
+
+ public string Title
+ {
+ get { return name.Text; }
+ set { name.Text = value; }
+ }
+
+ private float difficultyValue;
+ public float Value
+ {
+ get { return difficultyValue; }
+ set
+ {
+ difficultyValue = value;
+ bar.Length = value / maxValue;
+ this.value.Text = value.ToString(forceDecimalPlaces ? "0.00" : "0.##");
+ }
+ }
+
+ public Color4 AccentColour
+ {
+ get { return bar.AccentColour; }
+ set { bar.AccentColour = value; }
+ }
+
+ public StatisticRow(float maxValue = 10, bool forceDecimalPlaces = false)
+ {
+ this.maxValue = maxValue;
+ this.forceDecimalPlaces = forceDecimalPlaces;
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Width = name_width,
+ AutoSizeAxes = Axes.Y,
+ Child = name = new OsuSpriteText
+ {
+ TextSize = 13,
+ },
+ },
+ bar = new Bar
+ {
+ Origin = Anchor.CentreLeft,
+ Anchor = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.X,
+ Height = 5,
+ BackgroundColour = Color4.White.Opacity(0.5f),
+ Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
+ },
+ new Container
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ Width = value_width,
+ RelativeSizeAxes = Axes.Y,
+ Child = value = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ TextSize = 13,
+ },
+ },
+ };
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs
new file mode 100644
index 0000000000..4d75c49d17
--- /dev/null
+++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs
@@ -0,0 +1,62 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Graphics;
+using osu.Game.Graphics.UserInterface;
+using System.Linq;
+using osu.Game.Beatmaps;
+
+namespace osu.Game.Screens.Select.Details
+{
+ public class FailRetryGraph : Container
+ {
+ private readonly BarGraph retryGraph, failGraph;
+
+ private BeatmapMetrics metrics;
+ public BeatmapMetrics Metrics
+ {
+ get { return metrics; }
+ set
+ {
+ if (value == metrics) return;
+ metrics = value;
+
+ var retries = Metrics.Retries;
+ var fails = Metrics.Fails;
+
+ float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
+ failGraph.MaxValue = maxValue;
+ retryGraph.MaxValue = maxValue;
+
+ failGraph.Values = fails.Select(f => (float)f);
+ retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
+ }
+ }
+
+ public FailRetryGraph()
+ {
+ Children = new[]
+ {
+ retryGraph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ failGraph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ retryGraph.Colour = colours.Yellow;
+ failGraph.Colour = colours.YellowDarker;
+ }
+ }
+}
diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs
new file mode 100644
index 0000000000..db6d932464
--- /dev/null
+++ b/osu.Game/Screens/Select/Details/UserRatings.cs
@@ -0,0 +1,122 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// 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.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using System.Linq;
+using osu.Game.Beatmaps;
+
+namespace osu.Game.Screens.Select.Details
+{
+ public class UserRatings : Container
+ {
+ private readonly FillFlowContainer header;
+ private readonly Bar ratingsBar;
+ private readonly OsuSpriteText negativeRatings, positiveRatings;
+ private readonly Container graphContainer;
+ private readonly BarGraph graph;
+
+ private BeatmapMetrics metrics;
+ public BeatmapMetrics Metrics
+ {
+ get { return metrics; }
+ set
+ {
+ if (value == metrics) return;
+ metrics = value;
+
+ var ratings = Metrics.Ratings.ToList();
+ negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
+ positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
+ ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
+ graph.Values = Metrics.Ratings.Select(r => (float)r);
+ }
+ }
+
+ public UserRatings()
+ {
+ Children = new Drawable[]
+ {
+ header = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Text = "User Rating",
+ TextSize = 13,
+ },
+ ratingsBar = new Bar
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 5,
+ Margin = new MarginPadding { Top = 5 },
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new[]
+ {
+ negativeRatings = new OsuSpriteText
+ {
+ Text = "0",
+ TextSize = 13,
+ },
+ positiveRatings = new OsuSpriteText
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ Text = @"0",
+ TextSize = 13,
+ },
+ },
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Text = "Rating Spread",
+ TextSize = 13,
+ Margin = new MarginPadding { Top = 10, Bottom = 5 },
+ },
+ },
+ },
+ graphContainer = new Container
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ RelativeSizeAxes = Axes.Both,
+ Child = graph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ },
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ ratingsBar.BackgroundColour = colours.Green;
+ ratingsBar.AccentColour = colours.Yellow;
+ graph.Colour = colours.BlueDark;
+ }
+
+ protected override void UpdateAfterChildren()
+ {
+ base.UpdateAfterChildren();
+
+ graphContainer.Padding = new MarginPadding { Top = header.DrawHeight };
+ }
+ }
+}
diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
index 5a375e55d4..0506784614 100644
--- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
@@ -1,15 +1,15 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics;
+using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
-using System;
-using osu.Framework.Allocation;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
index 2987f4476c..de381cd2dc 100644
--- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
+++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
@@ -4,17 +4,19 @@
using System;
using OpenTK;
using OpenTK.Graphics;
+using osu.Framework;
+using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Input;
using osu.Game.Graphics;
-using osu.Game.Graphics.Sprites;
-using osu.Framework.Extensions.Color4Extensions;
-using osu.Game.Rulesets.Mods;
-using osu.Game.Users;
-using osu.Framework;
-using osu.Game.Rulesets.Scoring;
using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
+using osu.Game.Users;
namespace osu.Game.Screens.Select.Leaderboards
{
@@ -41,7 +43,7 @@ namespace osu.Game.Screens.Select.Leaderboards
private readonly ScoreComponentLabel maxCombo;
private readonly ScoreComponentLabel accuracy;
private readonly Container flagBadgeContainer;
- private readonly FillFlowContainer modsContainer;
+ private readonly FillFlowContainer modsContainer;
private Visibility state;
@@ -247,7 +249,7 @@ namespace osu.Game.Screens.Select.Leaderboards
},
},
},
- modsContainer = new FillFlowContainer
+ modsContainer = new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
@@ -260,13 +262,13 @@ namespace osu.Game.Screens.Select.Leaderboards
},
};
- if (Score.Mods != null)
+ foreach (Mod mod in Score.Mods)
{
- foreach (Mod mod in Score.Mods)
+ modsContainer.Add(new ModIcon(mod)
{
- // TODO: Get actual mod colours
- modsContainer.Add(new ScoreModIcon(mod.Icon, OsuColour.FromHex(@"ffcc22")));
- }
+ AutoSizeAxes = Axes.Both,
+ Scale = new Vector2(0.375f)
+ });
}
}
@@ -275,13 +277,13 @@ namespace osu.Game.Screens.Select.Leaderboards
public override void Hide() => State = Visibility.Hidden;
public override void Show() => State = Visibility.Visible;
- protected override bool OnHover(Framework.Input.InputState state)
+ protected override bool OnHover(InputState state)
{
background.FadeTo(0.5f, 300, Easing.OutQuint);
return base.OnHover(state);
}
- protected override void OnHoverLost(Framework.Input.InputState state)
+ protected override void OnHoverLost(InputState state)
{
background.FadeTo(background_alpha, 200, Easing.OutQuint);
base.OnHoverLost(state);
@@ -302,7 +304,7 @@ namespace osu.Game.Screens.Select.Leaderboards
BlurSigma = new Vector2(4),
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Size = new Vector2(3f),
Children = new[]
{
@@ -311,8 +313,8 @@ namespace osu.Game.Screens.Select.Leaderboards
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = font,
- TextSize = textSize,
FixedWidth = true,
+ TextSize = textSize,
Text = text,
Colour = glowColour,
Shadow = false,
@@ -334,36 +336,6 @@ namespace osu.Game.Screens.Select.Leaderboards
}
}
- private class ScoreModIcon : Container
- {
- public ScoreModIcon(FontAwesome icon, Color4 colour)
- {
- AutoSizeAxes = Axes.Both;
-
- Children = new[]
- {
- new SpriteIcon
- {
- Origin = Anchor.Centre,
- Anchor = Anchor.Centre,
- Icon = FontAwesome.fa_osu_mod_bg,
- Colour = colour,
- Shadow = true,
- Size = new Vector2(30),
- },
- new SpriteIcon
- {
- Origin = Anchor.Centre,
- Anchor = Anchor.Centre,
- Icon = icon,
- Colour = OsuColour.Gray(84),
- Size = new Vector2(18),
- Position = new Vector2(0f, 2f),
- },
- };
- }
- }
-
private class ScoreComponentLabel : Container
{
public ScoreComponentLabel(FontAwesome icon, string value)
diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
index 306e7fb3dc..5f1bdcc9bb 100644
--- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
+++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
@@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select.Options
{
RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(1.5f, 0),
- BlendingMode = BlendingMode.Additive,
+ Blending = BlendingMode.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 325cfba986..d20618a2ae 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -9,7 +9,7 @@
Properties
osu.Game
osu.Game
- v4.5
+ v4.6.1
512
@@ -98,6 +98,7 @@
+
@@ -133,6 +134,10 @@
+
+
+
+
@@ -534,6 +539,9 @@
+
+
+
diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings
index 06d160ad31..0b8c196ec8 100644
--- a/osu.sln.DotSettings
+++ b/osu.sln.DotSettings
@@ -190,6 +190,7 @@
IPC
LTRB
MD5
+ RGB
RNG
SHA
SRGB