diff --git a/Gemfile.lock b/Gemfile.lock
index 17c0db12e7..f7c19064b4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,7 +6,7 @@ GEM
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.3)
babosa (1.0.2)
- claide (1.0.2)
+ claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
@@ -14,11 +14,11 @@ GEM
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
- domain_name (0.5.20180417)
+ domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
- dotenv (2.7.1)
+ dotenv (2.7.5)
emoji_regex (1.0.1)
- excon (0.62.0)
+ excon (0.66.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
@@ -27,7 +27,7 @@ GEM
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
- fastlane (2.117.0)
+ fastlane (2.129.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
@@ -46,8 +46,8 @@ GEM
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
- mini_magick (~> 4.5.1)
- multi_json
+ jwt (~> 2.1.0)
+ mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
@@ -56,15 +56,15 @@ GEM
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
- terminal-notifier (>= 1.6.2, < 2.0.0)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
- xcodeproj (>= 1.6.0, < 2.0.0)
+ xcodeproj (>= 1.8.1, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
- fastlane-plugin-clean_testflight_testers (0.2.0)
+ fastlane-plugin-clean_testflight_testers (0.3.0)
fastlane-plugin-souyuz (0.8.1)
souyuz (>= 0.8.1)
fastlane-plugin-xamarin (0.6.3)
@@ -79,7 +79,7 @@ GEM
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
- google-cloud-env (1.0.5)
+ google-cloud-env (1.2.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
@@ -102,17 +102,17 @@ GEM
memoist (0.16.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
- mime-types-data (3.2018.0812)
- mini_magick (4.5.1)
+ mime-types-data (3.2019.0331)
+ mini_magick (4.9.5)
mini_portile2 (2.4.0)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
naturally (2.2.0)
- nokogiri (1.10.1)
+ nokogiri (1.10.4)
mini_portile2 (~> 2.4.0)
- os (1.0.0)
+ os (1.0.1)
plist (3.5.0)
public_suffix (2.0.5)
representable (3.0.4)
@@ -121,7 +121,7 @@ GEM
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
- rubyzip (1.2.2)
+ rubyzip (1.2.3)
security (0.1.3)
signet (0.11.0)
addressable (~> 2.3)
@@ -136,20 +136,20 @@ GEM
fastlane (>= 2.29.0)
highline (~> 1.7)
nokogiri (~> 1.7)
- terminal-notifier (1.8.0)
+ terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
- tty-cursor (0.6.1)
- tty-screen (0.6.5)
- tty-spinner (0.9.0)
- tty-cursor (~> 0.6.0)
+ tty-cursor (0.7.0)
+ tty-screen (0.7.0)
+ tty-spinner (0.9.1)
+ tty-cursor (~> 0.7)
uber (0.1.0)
unf (0.1.4)
unf_ext
- unf_ext (0.0.7.5)
- unicode-display_width (1.4.1)
+ unf_ext (0.0.7.6)
+ unicode-display_width (1.6.0)
word_wrap (1.0.0)
- xcodeproj (1.8.1)
+ xcodeproj (1.12.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 48c16caf0f..0b60e28b0f 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -1,22 +1,6 @@
update_fastlane
-default_platform(:ios)
-
platform :ios do
- lane :testflight_prune_dry do
- clean_testflight_testers(days_of_inactivity:45, dry_run: true)
- end
-
- # Specify a custom number for what's "inactive"
- lane :testflight_prune do
- clean_testflight_testers(days_of_inactivity: 45) # 120 days, so about 4 months
- end
-
- lane :update_version do |options|
- options[:plist_path] = '../osu.iOS/Info.plist'
- app_version(options)
- end
-
desc 'Deploy to testflight'
lane :beta do |options|
update_version(options)
@@ -62,4 +46,17 @@ platform :ios do
match(options)
end
+
+ lane :update_version do |options|
+ options[:plist_path] = '../osu.iOS/Info.plist'
+ app_version(options)
+ end
+
+ lane :testflight_prune_dry do
+ clean_testflight_testers(days_of_inactivity:45, dry_run: true)
+ end
+
+ lane :testflight_prune do
+ clean_testflight_testers(days_of_inactivity: 45)
+ end
end
diff --git a/fastlane/README.md b/fastlane/README.md
index 53bbc62cae..fbccf1c8c0 100644
--- a/fastlane/README.md
+++ b/fastlane/README.md
@@ -16,21 +16,6 @@ or alternatively using `brew cask install fastlane`
# Available Actions
## iOS
-### ios testflight_prune_dry
-```
-fastlane ios testflight_prune_dry
-```
-
-### ios testflight_prune
-```
-fastlane ios testflight_prune
-```
-
-### ios update_version
-```
-fastlane ios update_version
-```
-
### ios beta
```
fastlane ios beta
@@ -46,6 +31,21 @@ Compile the project
fastlane ios provision
```
Install provisioning profiles using match
+### ios update_version
+```
+fastlane ios update_version
+```
+
+### ios testflight_prune_dry
+```
+fastlane ios testflight_prune_dry
+```
+
+### ios testflight_prune
+```
+fastlane ios testflight_prune
+```
+
----
diff --git a/osu.Android.props b/osu.Android.props
index 7bc60ef884..215a9a8090 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -60,7 +60,7 @@
-
-
+
+
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index 4100404da6..7c282f449b 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
index ce2daebbf1..1af77b75fc 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AccentColour = Color4.Red,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0.5f,
Scale = new Vector2(1.333f)
});
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
index b9b6d5b924..1e9daf18db 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Colour = Color4.White.Opacity(0.9f);
}
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
index 0b06e958e6..62abe53559 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -201,7 +201,7 @@ namespace osu.Game.Rulesets.Catch.UI
additive.Scale = Scale;
additive.Colour = HyperDashing ? Color4.Red : Color4.White;
additive.RelativePositionAxes = RelativePositionAxes;
- additive.Blending = BlendingMode.Additive;
+ additive.Blending = BlendingParameters.Additive;
AdditiveTarget.Add(additive);
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index 013d2a71d4..4dcfc1b81f 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
index a92e56d3c3..31a4857805 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
@@ -26,14 +26,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public BodyPiece()
{
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Children = new[]
{
Background = new Box { RelativeSizeAxes = Axes.Both },
Foreground = new BufferedContainer
{
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
RelativeSizeAxes = Axes.Both,
CacheDrawnFrameBuffer = true,
Children = new Drawable[]
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
index 9e0307c5c2..48c7ea7b7f 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
Name = "Top",
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha))
},
new Box
@@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent)
}
};
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
index b4e29ae9f9..5ee78aa496 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
Name = "Background Gradient Overlay",
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0
}
};
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png
new file mode 100644
index 0000000000..bdb2bcbc41
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png
new file mode 100644
index 0000000000..7db8eb3124
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100k@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100k@2x.png
new file mode 100644
index 0000000000..206840e467
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100k@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png
new file mode 100644
index 0000000000..2c7c07852f
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png
new file mode 100644
index 0000000000..1ce746e3a4
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit50@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit50@2x.png
new file mode 100644
index 0000000000..94c09d263a
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit50@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png
new file mode 100644
index 0000000000..626fd91e38
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png
new file mode 100644
index 0000000000..76fd9ab168
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb0@2x.png
new file mode 100644
index 0000000000..0a24a72808
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png
new file mode 100644
index 0000000000..e99f076947
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png
new file mode 100644
index 0000000000..cd36a0ae16
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb3@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb3@2x.png
new file mode 100644
index 0000000000..f494bd3f51
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb3@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png
new file mode 100644
index 0000000000..a5b19887d6
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png
new file mode 100644
index 0000000000..4bb01f0e88
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png
new file mode 100644
index 0000000000..859e0aa4c1
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb7@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb7@2x.png
new file mode 100644
index 0000000000..90efda0994
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb7@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png
new file mode 100644
index 0000000000..fcdf4ed4a4
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png
new file mode 100644
index 0000000000..c990cf0fe6
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png
new file mode 100644
index 0000000000..a91072eb5b
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.png
new file mode 100644
index 0000000000..5eb202c021
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.png
new file mode 100644
index 0000000000..878c11cd67
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png
new file mode 100644
index 0000000000..f64feded0c
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png
new file mode 100644
index 0000000000..37e7e9143f
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png
new file mode 100644
index 0000000000..b75c71927c
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png
new file mode 100644
index 0000000000..7932667408
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png
new file mode 100644
index 0000000000..0b0ae85972
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png
new file mode 100644
index 0000000000..441c3ec21f
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-1@2x.png
new file mode 100644
index 0000000000..910d8e2231
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-1@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png
new file mode 100644
index 0000000000..6f92db28d3
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png
new file mode 100644
index 0000000000..b28503e9f2
Binary files /dev/null and b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png differ
diff --git a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs
index a2c058193b..02716dc1d5 100644
--- a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs
+++ b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs
@@ -2,12 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.IO;
-using System.Linq;
+using System.Text.RegularExpressions;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
using osu.Game.Skinning;
using osu.Game.Tests.Visual;
@@ -28,11 +28,11 @@ namespace osu.Game.Rulesets.Osu.Tests
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
- var skins = new SkinManager(LocalStorage, ContextFactory, null, audio);
+ var dllStore = new DllResourceStore("osu.Game.Rulesets.Osu.Tests.dll");
- metricsSkin = getSkinFromResources(skins, "metrics_skin");
- defaultSkin = getSkinFromResources(skins, "default_skin");
- specialSkin = getSkinFromResources(skins, "special_skin");
+ metricsSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore(dllStore, "Resources/metrics_skin"), audio, true);
+ defaultSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore(dllStore, "Resources/default_skin"), audio, false);
+ specialSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore(dllStore, "Resources/special_skin"), audio, true);
}
public void SetContents(Func creationFunction)
@@ -43,23 +43,28 @@ namespace osu.Game.Rulesets.Osu.Tests
Cell(3).Child = new LocalSkinOverrideContainer(specialSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction());
}
- private static Skin getSkinFromResources(SkinManager skins, string name)
+ private class TestLegacySkin : LegacySkin
{
- using (var storage = new DllResourceStore("osu.Game.Rulesets.Osu.Tests.dll"))
+ private readonly bool extrapolateAnimations;
+
+ public TestLegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager, bool extrapolateAnimations)
+ : base(skin, storage, audioManager, "skin.ini")
{
- var tempName = Path.GetTempFileName();
+ this.extrapolateAnimations = extrapolateAnimations;
+ }
- File.Delete(tempName);
- Directory.CreateDirectory(tempName);
+ public override Texture GetTexture(string componentName)
+ {
+ // extrapolate frames to test longer animations
+ if (extrapolateAnimations)
+ {
+ var match = Regex.Match(componentName, "-([0-9]*)");
- var files = storage.GetAvailableResources().Where(f => f.StartsWith($"Resources/{name}"));
+ if (match.Length > 0 && int.TryParse(match.Groups[1].Value, out var number) && number < 60)
+ return base.GetTexture(componentName.Replace($"-{number}", $"-{number % 2}"));
+ }
- foreach (var file in files)
- using (var stream = storage.GetStream(file))
- using (var newFile = File.Create(Path.Combine(tempName, Path.GetFileName(file))))
- stream.CopyTo(newFile);
-
- return skins.GetSkin(skins.Import(tempName).Result);
+ return base.GetTexture(componentName);
}
}
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs
new file mode 100644
index 0000000000..82a8d0e5e6
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs
@@ -0,0 +1,34 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Extensions;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ public class TestSceneDrawableJudgement : SkinnableTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(DrawableJudgement),
+ typeof(DrawableOsuJudgement)
+ };
+
+ public TestSceneDrawableJudgement()
+ {
+ foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1))
+ AddStep("Show " + result.GetDescription(), () => SetContents(() =>
+ new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null)
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ }));
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
index c5a27205d6..29c71a8903 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
@@ -10,7 +10,6 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
-using osu.Game.Tests.Visual;
using osuTK;
using osuTK.Graphics;
using osu.Game.Rulesets.Mods;
@@ -27,83 +26,96 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
- public class TestSceneSlider : OsuTestScene
+ public class TestSceneSlider : SkinnableTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
+ typeof(Slider),
+ typeof(SliderTick),
+ typeof(SliderTailCircle),
typeof(SliderBall),
typeof(SliderBody),
- typeof(SliderTick),
+ typeof(SnakingSliderBody),
typeof(DrawableSlider),
typeof(DrawableSliderTick),
+ typeof(DrawableSliderTail),
+ typeof(DrawableSliderHead),
typeof(DrawableRepeatPoint),
typeof(DrawableOsuHitObject)
};
- private readonly Container content;
- protected override Container Content => content;
+ private Container content;
+
+ protected override Container Content
+ {
+ get
+ {
+ if (content == null)
+ base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
+
+ return content;
+ }
+ }
private int depthIndex;
public TestSceneSlider()
{
- base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
+ AddStep("Big Single", () => SetContents(() => testSimpleBig()));
+ AddStep("Medium Single", () => SetContents(() => testSimpleMedium()));
+ AddStep("Small Single", () => SetContents(() => testSimpleSmall()));
+ AddStep("Big 1 Repeat", () => SetContents(() => testSimpleBig(1)));
+ AddStep("Medium 1 Repeat", () => SetContents(() => testSimpleMedium(1)));
+ AddStep("Small 1 Repeat", () => SetContents(() => testSimpleSmall(1)));
+ AddStep("Big 2 Repeats", () => SetContents(() => testSimpleBig(2)));
+ AddStep("Medium 2 Repeats", () => SetContents(() => testSimpleMedium(2)));
+ AddStep("Small 2 Repeats", () => SetContents(() => testSimpleSmall(2)));
- AddStep("Big Single", () => testSimpleBig());
- AddStep("Medium Single", () => testSimpleMedium());
- AddStep("Small Single", () => testSimpleSmall());
- AddStep("Big 1 Repeat", () => testSimpleBig(1));
- AddStep("Medium 1 Repeat", () => testSimpleMedium(1));
- AddStep("Small 1 Repeat", () => testSimpleSmall(1));
- AddStep("Big 2 Repeats", () => testSimpleBig(2));
- AddStep("Medium 2 Repeats", () => testSimpleMedium(2));
- AddStep("Small 2 Repeats", () => testSimpleSmall(2));
+ AddStep("Slow Slider", () => SetContents(testSlowSpeed)); // slow long sliders take ages already so no repeat steps
+ AddStep("Slow Short Slider", () => SetContents(() => testShortSlowSpeed()));
+ AddStep("Slow Short Slider 1 Repeats", () => SetContents(() => testShortSlowSpeed(1)));
+ AddStep("Slow Short Slider 2 Repeats", () => SetContents(() => testShortSlowSpeed(2)));
- AddStep("Slow Slider", testSlowSpeed); // slow long sliders take ages already so no repeat steps
- AddStep("Slow Short Slider", () => testShortSlowSpeed());
- AddStep("Slow Short Slider 1 Repeats", () => testShortSlowSpeed(1));
- AddStep("Slow Short Slider 2 Repeats", () => testShortSlowSpeed(2));
+ AddStep("Fast Slider", () => SetContents(() => testHighSpeed()));
+ AddStep("Fast Slider 1 Repeat", () => SetContents(() => testHighSpeed(1)));
+ AddStep("Fast Slider 2 Repeats", () => SetContents(() => testHighSpeed(2)));
+ AddStep("Fast Short Slider", () => SetContents(() => testShortHighSpeed()));
+ AddStep("Fast Short Slider 1 Repeat", () => SetContents(() => testShortHighSpeed(1)));
+ AddStep("Fast Short Slider 2 Repeats", () => SetContents(() => testShortHighSpeed(2)));
+ AddStep("Fast Short Slider 6 Repeats", () => SetContents(() => testShortHighSpeed(6)));
- AddStep("Fast Slider", () => testHighSpeed());
- AddStep("Fast Slider 1 Repeat", () => testHighSpeed(1));
- AddStep("Fast Slider 2 Repeats", () => testHighSpeed(2));
- AddStep("Fast Short Slider", () => testShortHighSpeed());
- AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1));
- AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2));
- AddStep("Fast Short Slider 6 Repeats", () => testShortHighSpeed(6));
+ AddStep("Perfect Curve", () => SetContents(() => testPerfect()));
+ AddStep("Perfect Curve 1 Repeat", () => SetContents(() => testPerfect(1)));
+ AddStep("Perfect Curve 2 Repeats", () => SetContents(() => testPerfect(2)));
- AddStep("Perfect Curve", () => testPerfect());
- AddStep("Perfect Curve 1 Repeat", () => testPerfect(1));
- AddStep("Perfect Curve 2 Repeats", () => testPerfect(2));
+ AddStep("Linear Slider", () => SetContents(() => testLinear()));
+ AddStep("Linear Slider 1 Repeat", () => SetContents(() => testLinear(1)));
+ AddStep("Linear Slider 2 Repeats", () => SetContents(() => testLinear(2)));
- AddStep("Linear Slider", () => testLinear());
- AddStep("Linear Slider 1 Repeat", () => testLinear(1));
- AddStep("Linear Slider 2 Repeats", () => testLinear(2));
+ AddStep("Bezier Slider", () => SetContents(() => testBezier()));
+ AddStep("Bezier Slider 1 Repeat", () => SetContents(() => testBezier(1)));
+ AddStep("Bezier Slider 2 Repeats", () => SetContents(() => testBezier(2)));
- AddStep("Bezier Slider", () => testBezier());
- AddStep("Bezier Slider 1 Repeat", () => testBezier(1));
- AddStep("Bezier Slider 2 Repeats", () => testBezier(2));
+ AddStep("Linear Overlapping", () => SetContents(() => testLinearOverlapping()));
+ AddStep("Linear Overlapping 1 Repeat", () => SetContents(() => testLinearOverlapping(1)));
+ AddStep("Linear Overlapping 2 Repeats", () => SetContents(() => testLinearOverlapping(2)));
- AddStep("Linear Overlapping", () => testLinearOverlapping());
- AddStep("Linear Overlapping 1 Repeat", () => testLinearOverlapping(1));
- AddStep("Linear Overlapping 2 Repeats", () => testLinearOverlapping(2));
+ AddStep("Catmull Slider", () => SetContents(() => testCatmull()));
+ AddStep("Catmull Slider 1 Repeat", () => SetContents(() => testCatmull(1)));
+ AddStep("Catmull Slider 2 Repeats", () => SetContents(() => testCatmull(2)));
- AddStep("Catmull Slider", () => testCatmull());
- AddStep("Catmull Slider 1 Repeat", () => testCatmull(1));
- AddStep("Catmull Slider 2 Repeats", () => testCatmull(2));
+ AddStep("Big Single, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset()));
+ AddStep("Big 1 Repeat, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset(1)));
- AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset());
- AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1));
-
- AddStep("Distance Overflow", () => testDistanceOverflow());
- AddStep("Distance Overflow 1 Repeat", () => testDistanceOverflow(1));
+ AddStep("Distance Overflow", () => SetContents(() => testDistanceOverflow()));
+ AddStep("Distance Overflow 1 Repeat", () => SetContents(() => testDistanceOverflow(1)));
}
- private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
+ private Drawable testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
- private void testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10);
+ private Drawable testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10);
- private void testDistanceOverflow(int repeats = 0)
+ private Drawable testDistanceOverflow(int repeats = 0)
{
var slider = new Slider
{
@@ -120,22 +132,22 @@ namespace osu.Game.Rulesets.Osu.Tests
StackHeight = 10
};
- addSlider(slider, 2, 2);
+ return createDrawable(slider, 2, 2);
}
- private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
+ private Drawable testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
- private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);
+ private Drawable testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);
- private void testSlowSpeed() => createSlider(speedMultiplier: 0.5);
+ private Drawable testSlowSpeed() => createSlider(speedMultiplier: 0.5);
- private void testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5);
+ private Drawable testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5);
- private void testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15);
+ private Drawable testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15);
- private void testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15);
+ private Drawable testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15);
- private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2, int stackHeight = 0)
+ private Drawable createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2, int stackHeight = 0)
{
var slider = new Slider
{
@@ -151,10 +163,10 @@ namespace osu.Game.Rulesets.Osu.Tests
StackHeight = stackHeight
};
- addSlider(slider, circleSize, speedMultiplier);
+ return createDrawable(slider, circleSize, speedMultiplier);
}
- private void testPerfect(int repeats = 0)
+ private Drawable testPerfect(int repeats = 0)
{
var slider = new Slider
{
@@ -170,12 +182,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats)
};
- addSlider(slider, 2, 3);
+ return createDrawable(slider, 2, 3);
}
- private void testLinear(int repeats = 0) => createLinear(repeats);
+ private Drawable testLinear(int repeats = 0) => createLinear(repeats);
- private void createLinear(int repeats)
+ private Drawable createLinear(int repeats)
{
var slider = new Slider
{
@@ -194,12 +206,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats)
};
- addSlider(slider, 2, 3);
+ return createDrawable(slider, 2, 3);
}
- private void testBezier(int repeats = 0) => createBezier(repeats);
+ private Drawable testBezier(int repeats = 0) => createBezier(repeats);
- private void createBezier(int repeats)
+ private Drawable createBezier(int repeats)
{
var slider = new Slider
{
@@ -217,12 +229,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats)
};
- addSlider(slider, 2, 3);
+ return createDrawable(slider, 2, 3);
}
- private void testLinearOverlapping(int repeats = 0) => createOverlapping(repeats);
+ private Drawable testLinearOverlapping(int repeats = 0) => createOverlapping(repeats);
- private void createOverlapping(int repeats)
+ private Drawable createOverlapping(int repeats)
{
var slider = new Slider
{
@@ -241,12 +253,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats)
};
- addSlider(slider, 2, 3);
+ return createDrawable(slider, 2, 3);
}
- private void testCatmull(int repeats = 0) => createCatmull(repeats);
+ private Drawable testCatmull(int repeats = 0) => createCatmull(repeats);
- private void createCatmull(int repeats = 0)
+ private Drawable createCatmull(int repeats = 0)
{
var repeatSamples = new List>();
for (int i = 0; i < repeats; i++)
@@ -267,7 +279,7 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = repeatSamples
};
- addSlider(slider, 3, 1);
+ return createDrawable(slider, 3, 1);
}
private List> createEmptySamples(int repeats)
@@ -278,7 +290,7 @@ namespace osu.Game.Rulesets.Osu.Tests
return repeatSamples;
}
- private void addSlider(Slider slider, float circleSize, double speedMultiplier)
+ private Drawable createDrawable(Slider slider, float circleSize, double speedMultiplier)
{
var cpi = new ControlPointInfo();
cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier });
@@ -296,7 +308,7 @@ namespace osu.Game.Rulesets.Osu.Tests
drawable.OnNewResult += onNewResult;
- Add(drawable);
+ return drawable;
}
private float judgementOffsetDirection = 1;
diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
index 92c5c77aac..197309c7c4 100644
--- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
+++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
index a2a23e9ff7..523e911434 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
@@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
Child = new Box
{
Size = new Vector2(width),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0.5f,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs
index f75b62eecf..1db1eec33e 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Origin = Anchor.Centre;
InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
index c92937ef09..a59cfc1123 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
@@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
new TrianglesPiece
{
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.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 8ff16f8b84..1d21347cba 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
@@ -17,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Alpha = 0;
Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece
{
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
}, s => s.GetTexture("Play/osu/hitcircle") == null);
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
index c22073f56c..1e3af567fe 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Alpha = 0;
Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
index 917695c790..a36d9e96c8 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = textures.Get(name),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0.5f
}, s => s.GetTexture("Play/osu/hitcircle") == null);
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
index 8b72b23ca3..329aed7b81 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.drawableSlider = drawableSlider;
this.slider = slider;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Origin = Anchor.Centre;
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
@@ -55,7 +55,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Child = new Container
{
RelativeSizeAxes = Axes.Both,
- // TODO: support skin filename animation (sliderb0, sliderb1...)
Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()),
}
}
@@ -168,9 +167,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
return action == OsuAction.LeftButton || action == OsuAction.RightButton;
}
+ private Vector2? lastPosition;
+
public void UpdateProgress(double completionProgress)
{
- Position = slider.CurvePositionAt(completionProgress);
+ var newPos = slider.CurvePositionAt(completionProgress);
+
+ var diff = lastPosition.HasValue ? lastPosition.Value - newPos : newPos - slider.CurvePositionAt(completionProgress + 0.01f);
+ if (diff == Vector2.Zero)
+ return;
+
+ Position = newPos;
+ Rotation = -90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI);
+
+ lastPosition = newPos;
}
private class FollowCircleContainer : Container
@@ -190,7 +200,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Masking = true,
BorderThickness = 5,
BorderColour = Color4.Orange,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Child = new Box
{
Colour = Color4.Orange,
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index 82055ecaee..a5db1625d9 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index 5ec9dc61e2..82448ec7d5 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Origin = Anchor.Centre,
Alpha = 0,
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Masking = true,
Children = new[]
{
@@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = target_ring_thick_border,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.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 b7db819717..d9c0664ecd 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0,
AlwaysPresent = true
}
diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index aa37ff7008..d6866c7d25 100644
--- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
centre = new Sprite
{
@@ -124,7 +124,7 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f),
Alpha = 0,
- Blending = BlendingMode.Additive
+ Blending = BlendingParameters.Additive
}
};
}
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index 7427a3235d..e62dc45cab 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,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
HitTarget = new HitTarget
{
@@ -127,14 +127,14 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Blending = BlendingMode.Additive
+ Blending = BlendingParameters.Additive
},
judgementContainer = new JudgementContainer
{
Name = "Judgements",
RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Blending = BlendingMode.Additive
+ Blending = BlendingParameters.Additive
},
}
},
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs
index d42b61ea55..0c5ead10cf 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs
@@ -17,6 +17,8 @@ namespace osu.Game.Tests.Visual.Gameplay
{
private bool exitAction;
+ protected override double TimePerAction => 100; // required for the early exit test, since hold-to-confirm delay is 200ms
+
[BackgroundDependencyLoader]
private void load()
{
diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
index daee419b52..8f19df65a9 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
@@ -135,6 +135,9 @@ namespace osu.Game.Tests.Visual.Online
});
downloadAssert(true);
+
+ AddStep("show many difficulties", () => overlay.ShowBeatmapSet(createManyDifficultiesBeatmapSet()));
+ downloadAssert(true);
}
[Test]
@@ -222,6 +225,56 @@ namespace osu.Game.Tests.Visual.Online
AddStep(@"show without reload", overlay.Show);
}
+ private BeatmapSetInfo createManyDifficultiesBeatmapSet()
+ {
+ var beatmaps = new List();
+
+ for (int i = 1; i < 41; i++)
+ {
+ beatmaps.Add(new BeatmapInfo
+ {
+ OnlineBeatmapID = i * 10,
+ Version = $"Test #{i}",
+ Ruleset = Ruleset.Value,
+ StarDifficulty = 2 + i * 0.1,
+ BaseDifficulty = new BeatmapDifficulty
+ {
+ OverallDifficulty = 3.5f,
+ },
+ OnlineInfo = new BeatmapOnlineInfo(),
+ Metrics = new BeatmapMetrics
+ {
+ Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(),
+ Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(),
+ },
+ });
+ }
+
+ return new BeatmapSetInfo
+ {
+ OnlineBeatmapSetID = 123,
+ Metadata = new BeatmapMetadata
+ {
+ Title = @"many difficulties beatmap",
+ Artist = @"none",
+ Author = new User
+ {
+ Username = @"BanchoBot",
+ Id = 3,
+ },
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ Preview = @"https://b.ppy.sh/preview/123.mp3",
+ HasVideo = true,
+ HasStoryboard = true,
+ Covers = new BeatmapSetOnlineCovers(),
+ },
+ Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() },
+ Beatmaps = beatmaps,
+ };
+ }
+
private void downloadAssert(bool shown)
{
AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.DownloadButtonsVisible == shown);
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
index 53dbaeddda..731cb62518 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Overlays.Direct;
using osu.Game.Rulesets;
-using osu.Game.Rulesets.Osu;
using osu.Game.Users;
using osuTK;
@@ -24,7 +23,7 @@ namespace osu.Game.Tests.Visual.Online
typeof(IconPill)
};
- private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) => new BeatmapSetInfo
+ private BeatmapSetInfo getUndownloadableBeatmapSet() => new BeatmapSetInfo
{
OnlineBeatmapSetID = 123,
Metadata = new BeatmapMetadata
@@ -56,23 +55,62 @@ namespace osu.Game.Tests.Visual.Online
{
new BeatmapInfo
{
- Ruleset = ruleset,
+ Ruleset = Ruleset.Value,
Version = "Test",
StarDifficulty = 6.42,
}
}
};
- [BackgroundDependencyLoader]
- private void load()
+ private BeatmapSetInfo getManyDifficultiesBeatmapSet(RulesetStore rulesets)
{
- var ruleset = new OsuRuleset().RulesetInfo;
+ var beatmaps = new List();
- var normal = CreateWorkingBeatmap(ruleset).BeatmapSetInfo;
+ for (int i = 0; i < 100; i++)
+ {
+ beatmaps.Add(new BeatmapInfo
+ {
+ Ruleset = rulesets.GetRuleset(i % 4),
+ StarDifficulty = 2 + i % 4 * 2,
+ BaseDifficulty = new BeatmapDifficulty
+ {
+ OverallDifficulty = 3.5f,
+ }
+ });
+ }
+
+ return new BeatmapSetInfo
+ {
+ OnlineBeatmapSetID = 1,
+ Metadata = new BeatmapMetadata
+ {
+ Title = "many difficulties beatmap",
+ Artist = "test",
+ Author = new User
+ {
+ Username = "BanchoBot",
+ Id = 3,
+ }
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ HasVideo = true,
+ HasStoryboard = true,
+ Covers = new BeatmapSetOnlineCovers(),
+ },
+ Beatmaps = beatmaps,
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(RulesetStore rulesets)
+ {
+ var normal = CreateWorkingBeatmap(Ruleset.Value).BeatmapSetInfo;
normal.OnlineInfo.HasVideo = true;
normal.OnlineInfo.HasStoryboard = true;
- var undownloadable = getUndownloadableBeatmapSet(ruleset);
+ var undownloadable = getUndownloadableBeatmapSet();
+ var manyDifficulties = getManyDifficultiesBeatmapSet(rulesets);
Child = new BasicScrollContainer
{
@@ -81,15 +119,17 @@ namespace osu.Game.Tests.Visual.Online
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Vertical,
+ Direction = FillDirection.Full,
Padding = new MarginPadding(20),
- Spacing = new Vector2(0, 20),
+ Spacing = new Vector2(5, 20),
Children = new Drawable[]
{
new DirectGridPanel(normal),
- new DirectListPanel(normal),
new DirectGridPanel(undownloadable),
+ new DirectGridPanel(manyDifficulties),
+ new DirectListPanel(normal),
new DirectListPanel(undownloadable),
+ new DirectListPanel(manyDifficulties),
},
},
};
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
index 7c9b7c7815..6669ec7da3 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
@@ -516,6 +516,7 @@ namespace osu.Game.Tests.Visual.SongSelect
OnlineBeatmapID = b * 10,
Path = $"extra{b}.osu",
Version = $"Extra {b}",
+ Ruleset = rulesets.GetRuleset((b - 1) % 4),
StarDifficulty = 2,
BaseDifficulty = new BeatmapDifficulty
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs
index 23d9112b25..e95f4c09c6 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs
@@ -249,7 +249,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Size = new Vector2(50);
Masking = true;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
Alpha = 0.5f;
Child = new Box { RelativeSizeAxes = Axes.Both };
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs
index 7e6cf1285e..f787754aa4 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Menu;
@@ -12,7 +13,13 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneHoldToConfirmOverlay : OsuTestScene
{
- public override IReadOnlyList RequiredTypes => new[] { typeof(ExitConfirmOverlay) };
+ protected override double TimePerAction => 100; // required for the early exit test, since hold-to-confirm delay is 200ms
+
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(ExitConfirmOverlay),
+ typeof(HoldToConfirmContainer),
+ };
public TestSceneHoldToConfirmOverlay()
{
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 50530088c2..4a9d88f3a6 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index 257db89a20..2a8bd393da 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -7,7 +7,7 @@
-
+
WinExe
diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
index d5e28c1e3e..f6c1be0e36 100644
--- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
+++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
@@ -125,7 +125,7 @@ namespace osu.Game.Tournament.Components
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Gray,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0,
},
});
diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs
index 8042f6b4b9..198046df4f 100644
--- a/osu.Game/Beatmaps/BeatmapInfo.cs
+++ b/osu.Game/Beatmaps/BeatmapInfo.cs
@@ -129,6 +129,23 @@ namespace osu.Game.Beatmaps
///
public List Scores { get; set; }
+ [JsonIgnore]
+ public DifficultyRating DifficultyRating
+ {
+ get
+ {
+ var rating = StarDifficulty;
+
+ if (rating < 2.0) return DifficultyRating.Easy;
+ if (rating < 2.7) return DifficultyRating.Normal;
+ if (rating < 4.0) return DifficultyRating.Hard;
+ if (rating < 5.3) return DifficultyRating.Insane;
+ if (rating < 6.5) return DifficultyRating.Expert;
+
+ return DifficultyRating.ExpertPlus;
+ }
+ }
+
public override string ToString() => $"{Metadata} [{Version}]".Trim();
public bool Equals(BeatmapInfo other)
diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
index 5657b8fb8a..2d8a0b1249 100644
--- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
@@ -138,19 +138,15 @@ namespace osu.Game.Beatmaps
protected override Skin GetSkin()
{
- Skin skin;
-
try
{
- skin = new LegacyBeatmapSkin(BeatmapInfo, store, AudioManager);
+ return new LegacyBeatmapSkin(BeatmapInfo, store, AudioManager);
}
catch (Exception e)
{
Logger.Error(e, "Skin failed to load");
- skin = new DefaultSkin();
+ return null;
}
-
- return skin;
}
}
}
diff --git a/osu.Game/Beatmaps/DifficultyRating.cs b/osu.Game/Beatmaps/DifficultyRating.cs
new file mode 100644
index 0000000000..f0ee0ad705
--- /dev/null
+++ b/osu.Game/Beatmaps/DifficultyRating.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+namespace osu.Game.Beatmaps
+{
+ public enum DifficultyRating
+ {
+ Easy,
+ Normal,
+ Hard,
+ Insane,
+ Expert,
+ ExpertPlus
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
deleted file mode 100644
index 26ffcca1ec..0000000000
--- a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using System;
-using osu.Framework.Allocation;
-using osu.Framework.Graphics.Containers;
-using osu.Game.Graphics;
-using osuTK.Graphics;
-
-namespace osu.Game.Beatmaps.Drawables
-{
- public abstract class DifficultyColouredContainer : Container, IHasAccentColour
- {
- public Color4 AccentColour { get; set; }
-
- private readonly BeatmapInfo beatmap;
- private OsuColour palette;
-
- protected DifficultyColouredContainer(BeatmapInfo beatmap)
- {
- this.beatmap = beatmap;
- }
-
- [BackgroundDependencyLoader]
- private void load(OsuColour palette)
- {
- if (palette == null)
- throw new ArgumentNullException(nameof(palette));
-
- this.palette = palette;
- AccentColour = getColour(beatmap);
- }
-
- private enum DifficultyRating
- {
- Easy,
- Normal,
- Hard,
- Insane,
- Expert,
- ExpertPlus
- }
-
- private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
- {
- if (beatmap == null)
- throw new ArgumentNullException(nameof(beatmap));
-
- var rating = beatmap.StarDifficulty;
-
- if (rating < 2.0) return DifficultyRating.Easy;
- if (rating < 2.7) return DifficultyRating.Normal;
- if (rating < 4.0) return DifficultyRating.Hard;
- if (rating < 5.3) return DifficultyRating.Insane;
- if (rating < 6.5) return DifficultyRating.Expert;
-
- return DifficultyRating.ExpertPlus;
- }
-
- private Color4 getColour(BeatmapInfo beatmap)
- {
- switch (getDifficultyRating(beatmap))
- {
- case DifficultyRating.Easy:
- return palette.Green;
-
- default:
- case DifficultyRating.Normal:
- return palette.Blue;
-
- case DifficultyRating.Hard:
- return palette.Yellow;
-
- case DifficultyRating.Insane:
- return palette.Pink;
-
- case DifficultyRating.Expert:
- return palette.Purple;
-
- case DifficultyRating.ExpertPlus:
- return palette.Gray0;
- }
- }
- }
-}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 0a0ad28fdf..81f517dd86 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -1,4 +1,4 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
@@ -6,35 +6,58 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
- public class DifficultyIcon : DifficultyColouredContainer
+ public class DifficultyIcon : CompositeDrawable, IHasCustomTooltip
{
+ private readonly BeatmapInfo beatmap;
private readonly RulesetInfo ruleset;
- public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null)
- : base(beatmap)
+ private readonly Container iconContainer;
+
+ ///
+ /// Size of this difficulty icon.
+ ///
+ public new Vector2 Size
{
- if (beatmap == null)
- throw new ArgumentNullException(nameof(beatmap));
-
- this.ruleset = ruleset ?? beatmap.Ruleset;
-
- Size = new Vector2(20);
+ get => iconContainer.Size;
+ set => iconContainer.Size = value;
}
- [BackgroundDependencyLoader]
- private void load()
+ public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, bool shouldShowTooltip = true)
{
- Children = new Drawable[]
+ this.beatmap = beatmap ?? throw new ArgumentNullException(nameof(beatmap));
+
+ this.ruleset = ruleset ?? beatmap.Ruleset;
+ if (shouldShowTooltip)
+ TooltipContent = beatmap;
+
+ AutoSizeAxes = Axes.Both;
+
+ InternalChild = iconContainer = new Container { Size = new Vector2(20f) };
+ }
+
+ public string TooltipText { get; set; }
+
+ public ITooltip GetCustomTooltip() => new DifficultyIconTooltip();
+
+ public object TooltipContent { get; set; }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ iconContainer.Children = new Drawable[]
{
new CircularContainer
{
@@ -52,7 +75,7 @@ namespace osu.Game.Beatmaps.Drawables
Child = new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = AccentColour,
+ Colour = colours.ForDifficultyRating(beatmap.DifficultyRating),
},
},
new ConstrainedIconContainer
@@ -65,5 +88,96 @@ namespace osu.Game.Beatmaps.Drawables
}
};
}
+
+ private class DifficultyIconTooltip : VisibilityContainer, ITooltip
+ {
+ private readonly OsuSpriteText difficultyName, starRating;
+ private readonly Box background;
+
+ private readonly FillFlowContainer difficultyFlow;
+
+ public DifficultyIconTooltip()
+ {
+ AutoSizeAxes = Axes.Both;
+ Masking = true;
+ CornerRadius = 5;
+
+ Children = new Drawable[]
+ {
+ background = new Box
+ {
+ RelativeSizeAxes = Axes.Both
+ },
+ new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ AutoSizeDuration = 200,
+ AutoSizeEasing = Easing.OutQuint,
+ Direction = FillDirection.Vertical,
+ Padding = new MarginPadding(10),
+ Children = new Drawable[]
+ {
+ difficultyName = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold),
+ },
+ difficultyFlow = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Direction = FillDirection.Horizontal,
+ Children = new Drawable[]
+ {
+ starRating = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular),
+ },
+ new SpriteIcon
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Margin = new MarginPadding { Left = 4 },
+ Icon = FontAwesome.Solid.Star,
+ Size = new Vector2(12),
+ },
+ }
+ }
+ }
+ }
+ };
+ }
+
+ private OsuColour colours;
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ this.colours = colours;
+ background.Colour = colours.Gray3;
+ }
+
+ public bool SetContent(object content)
+ {
+ if (!(content is BeatmapInfo beatmap))
+ return false;
+
+ difficultyName.Text = beatmap.Version;
+ starRating.Text = $"{beatmap.StarDifficulty:0.##}";
+ difficultyFlow.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating);
+
+ return true;
+ }
+
+ public void Move(Vector2 pos) => Position = pos;
+
+ protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
+
+ protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
+ }
}
}
diff --git a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs
new file mode 100644
index 0000000000..fbad113caa
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs
@@ -0,0 +1,37 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Graphics;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Rulesets;
+using osuTK.Graphics;
+
+namespace osu.Game.Beatmaps.Drawables
+{
+ ///
+ /// A difficulty icon that contains a counter on the right-side of it.
+ ///
+ ///
+ /// Used in cases when there are too many difficulty icons to show.
+ ///
+ public class GroupedDifficultyIcon : DifficultyIcon
+ {
+ public GroupedDifficultyIcon(List beatmaps, RulesetInfo ruleset, Color4 counterColour)
+ : base(beatmaps.OrderBy(b => b.StarDifficulty).Last(), ruleset, false)
+ {
+ AddInternal(new OsuSpriteText
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ Padding = new MarginPadding { Left = Size.X },
+ Margin = new MarginPadding { Left = 2, Right = 5 },
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold),
+ Text = beatmaps.Count.ToString(),
+ Colour = counterColour,
+ });
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
index 3ae1c3ef12..17df9ccc7e 100644
--- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
@@ -246,7 +246,7 @@ namespace osu.Game.Beatmaps.Formats
switch (type)
{
case "A":
- timelineGroup?.BlendingMode.Add(easing, startTime, endTime, BlendingMode.Additive, startTime == endTime ? BlendingMode.Additive : BlendingMode.Inherit);
+ timelineGroup?.BlendingParameters.Add(easing, startTime, endTime, BlendingParameters.Additive, startTime == endTime ? BlendingParameters.Additive : BlendingParameters.Inherit);
break;
case "H":
diff --git a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs
index cda5e150de..773265d19b 100644
--- a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs
+++ b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs
@@ -12,9 +12,11 @@ namespace osu.Game.Graphics.Containers
{
public Action Action;
- private const int activate_delay = 400;
+ private const int default_activation_delay = 200;
private const int fadeout_delay = 200;
+ private readonly double activationDelay;
+
private bool fired;
private bool confirming;
@@ -25,13 +27,22 @@ namespace osu.Game.Graphics.Containers
public Bindable Progress = new BindableDouble();
+ ///
+ /// Create a new instance.
+ ///
+ /// The time requried before an action is confirmed.
+ protected HoldToConfirmContainer(double activationDelay = default_activation_delay)
+ {
+ this.activationDelay = activationDelay;
+ }
+
protected void BeginConfirm()
{
if (confirming || (!AllowMultipleFires && fired)) return;
confirming = true;
- this.TransformBindableTo(Progress, 1, activate_delay * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm());
+ this.TransformBindableTo(Progress, 1, activationDelay * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm());
}
protected virtual void Confirm()
diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
index 5606328575..0f7b26835b 100644
--- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
+++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
@@ -15,6 +15,7 @@ using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers
{
+ [Cached(typeof(IPreviewTrackOwner))]
public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler
{
private SampleChannel samplePopIn;
@@ -38,13 +39,6 @@ namespace osu.Game.Graphics.Containers
protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All);
- protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
- {
- var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
- dependencies.CacheAs(this);
- return dependencies;
- }
-
[BackgroundDependencyLoader(true)]
private void load(AudioManager audio)
{
diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs
index 8fc8dec9fd..2721ce55dc 100644
--- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs
+++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs
@@ -98,7 +98,7 @@ namespace osu.Game.Graphics.Containers
public OsuScrollbar(Direction scrollDir)
: base(scrollDir)
{
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
CornerRadius = 5;
diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs
index 092a23e787..e103798355 100644
--- a/osu.Game/Graphics/Cursor/MenuCursor.cs
+++ b/osu.Game/Graphics/Cursor/MenuCursor.cs
@@ -150,7 +150,7 @@ namespace osu.Game.Graphics.Cursor
},
AdditiveLayer = new Sprite
{
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = colour.Pink,
Alpha = 0,
Texture = textures.Get(@"Cursor/menu-cursor-additive"),
diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs
index cfcda892fd..57f39bb8c7 100644
--- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs
+++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs
@@ -30,22 +30,24 @@ namespace osu.Game.Graphics.Cursor
private readonly OsuSpriteText text;
private bool instantMovement = true;
- public override string TooltipText
+ public override bool SetContent(object content)
{
- set
+ if (!(content is string contentString))
+ return false;
+
+ if (contentString == text.Text) return true;
+
+ text.Text = contentString;
+
+ if (IsPresent)
{
- if (value == text.Text) return;
-
- text.Text = value;
-
- if (IsPresent)
- {
- AutoSizeDuration = 250;
- background.FlashColour(OsuColour.Gray(0.4f), 1000, Easing.OutQuint);
- }
- else
- AutoSizeDuration = 0;
+ AutoSizeDuration = 250;
+ background.FlashColour(OsuColour.Gray(0.4f), 1000, Easing.OutQuint);
}
+ else
+ AutoSizeDuration = 0;
+
+ return true;
}
public OsuTooltip()
diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs
index 63ec24f84f..af66f57f14 100644
--- a/osu.Game/Graphics/OsuColour.cs
+++ b/osu.Game/Graphics/OsuColour.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using osu.Game.Beatmaps;
using osuTK.Graphics;
namespace osu.Game.Graphics
@@ -37,6 +38,31 @@ namespace osu.Game.Graphics
}
}
+ public Color4 ForDifficultyRating(DifficultyRating difficulty)
+ {
+ switch (difficulty)
+ {
+ case DifficultyRating.Easy:
+ return Green;
+
+ default:
+ case DifficultyRating.Normal:
+ return Blue;
+
+ case DifficultyRating.Hard:
+ return Yellow;
+
+ case DifficultyRating.Insane:
+ return Pink;
+
+ case DifficultyRating.Expert:
+ return Purple;
+
+ case DifficultyRating.ExpertPlus:
+ return Gray0;
+ }
+ }
+
// See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less
public readonly Color4 PurpleLighter = FromHex(@"eeeeff");
public readonly Color4 PurpleLight = FromHex(@"aa88ff");
diff --git a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs
index 74e387d60e..24816deeb5 100644
--- a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs
+++ b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs
@@ -56,7 +56,7 @@ namespace osu.Game.Graphics.Sprites
BlurSigma = new Vector2(4),
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Size = new Vector2(3f),
Children = new[]
{
diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs
index b50bf14bab..927ad13829 100644
--- a/osu.Game/Graphics/UserInterface/DialogButton.cs
+++ b/osu.Game/Graphics/UserInterface/DialogButton.cs
@@ -254,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.Add(flash);
flash.Colour = ButtonColour;
- flash.Blending = BlendingMode.Additive;
+ flash.Blending = BlendingParameters.Additive;
flash.Alpha = 0.3f;
flash.FadeOutFromOne(click_duration);
flash.Expire();
diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs
index 1a8fea4ff9..660bd7979f 100644
--- a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs
+++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs
@@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface
{
RelativeSizeAxes = Axes.Both,
Colour = HoverColour,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0,
},
}
diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs
index 7a27f825f6..c1810800a0 100644
--- a/osu.Game/Graphics/UserInterface/OsuButton.cs
+++ b/osu.Game/Graphics/UserInterface/OsuButton.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface
hover = new Box
{
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = Color4.White.Opacity(0.1f),
Alpha = 0,
Depth = -1
diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
index 47324ee646..6593531099 100644
--- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
@@ -72,17 +72,11 @@ namespace osu.Game.Graphics.UserInterface
Current.DisabledChanged += disabled => labelText.Alpha = Nub.Alpha = disabled ? 0.3f : 1;
}
- protected override void LoadComplete()
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
{
- base.LoadComplete();
-
- Current.ValueChanged += enabled =>
- {
- if (enabled.NewValue)
- sampleChecked?.Play();
- else
- sampleUnchecked?.Play();
- };
+ sampleChecked = audio.Samples.Get(@"UI/check-on");
+ sampleUnchecked = audio.Samples.Get(@"UI/check-off");
}
protected override bool OnHover(HoverEvent e)
@@ -99,11 +93,13 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(e);
}
- [BackgroundDependencyLoader]
- private void load(AudioManager audio)
+ protected override void OnUserChange(bool value)
{
- sampleChecked = audio.Samples.Get(@"UI/check-on");
- sampleUnchecked = audio.Samples.Get(@"UI/check-off");
+ base.OnUserChange(value);
+ if (value)
+ sampleChecked?.Play();
+ else
+ sampleUnchecked?.Play();
}
}
}
diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs
index 4aaffdd161..db26945ef3 100644
--- a/osu.Game/Online/Chat/MessageFormatter.cs
+++ b/osu.Game/Online/Chat/MessageFormatter.cs
@@ -122,6 +122,7 @@ namespace osu.Game.Online.Chat
return new LinkDetails(LinkAction.OpenBeatmapSet, args[3]);
case "u":
+ case "users":
return new LinkDetails(LinkAction.OpenUserProfile, args[3]);
}
}
diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
index baf702eebc..28947b6f22 100644
--- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
+++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
@@ -91,7 +91,8 @@ namespace osu.Game.Overlays.BeatmapSet
{
difficulties = new DifficultiesContainer
{
- AutoSizeAxes = Axes.Both,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) },
OnLostHover = () =>
{
@@ -234,7 +235,7 @@ namespace osu.Game.Overlays.BeatmapSet
Colour = Color4.Black.Opacity(0.5f),
},
},
- icon = new DifficultyIcon(beatmap)
+ icon = new DifficultyIcon(beatmap, shouldShowTooltip: false)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs
index 243e79eb9b..7bf94c1483 100644
--- a/osu.Game/Overlays/Direct/DirectGridPanel.cs
+++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs
@@ -151,7 +151,7 @@ namespace osu.Game.Overlays.Direct
AutoSizeAxes = Axes.X,
Height = 20,
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
- Children = GetDifficultyIcons(),
+ Children = GetDifficultyIcons(colours),
},
},
},
diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs
index 5757e1445b..158ff648dd 100644
--- a/osu.Game/Overlays/Direct/DirectListPanel.cs
+++ b/osu.Game/Overlays/Direct/DirectListPanel.cs
@@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Direct
AutoSizeAxes = Axes.X,
Height = 20,
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
- Children = GetDifficultyIcons(),
+ Children = GetDifficultyIcons(colours),
},
},
},
diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs
index 8199d80528..641423f21f 100644
--- a/osu.Game/Overlays/Direct/DirectPanel.cs
+++ b/osu.Game/Overlays/Direct/DirectPanel.cs
@@ -28,6 +28,7 @@ namespace osu.Game.Overlays.Direct
public readonly BeatmapSetInfo SetInfo;
private const double hover_transition_time = 400;
+ private const int maximum_difficulty_icons = 15;
private Container content;
@@ -138,12 +139,18 @@ namespace osu.Game.Overlays.Direct
};
}
- protected List GetDifficultyIcons()
+ protected List GetDifficultyIcons(OsuColour colours)
{
var icons = new List();
- foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty))
- icons.Add(new DifficultyIcon(b));
+ if (SetInfo.Beatmaps.Count > maximum_difficulty_icons)
+ {
+ foreach (var ruleset in SetInfo.Beatmaps.Select(b => b.Ruleset).Distinct())
+ icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset)), ruleset, this is DirectListPanel ? Color4.White : colours.Gray5));
+ }
+ else
+ foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty))
+ icons.Add(new DifficultyIcon(b));
return icons;
}
diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs
index f6208c46cb..6ad147735b 100644
--- a/osu.Game/Overlays/MusicController.cs
+++ b/osu.Game/Overlays/MusicController.cs
@@ -92,6 +92,15 @@ namespace osu.Game.Overlays
});
}
+ ///
+ /// Start playing the current track (if not already playing).
+ ///
+ public void Play()
+ {
+ if (!IsPlaying)
+ TogglePause();
+ }
+
///
/// Toggle pause / play.
///
diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
index e7f7c2f490..158641d816 100644
--- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
@@ -140,6 +140,9 @@ namespace osu.Game.Overlays.Profile.Header
{
if (string.IsNullOrEmpty(content)) return;
+ // newlines could be contained in API returned user content.
+ content = content.Replace("\n", " ");
+
bottomLinkContainer.AddIcon(icon, text =>
{
text.Font = text.Font.With(size: 10);
diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs
index 9cb9d48de7..24ed0cc022 100644
--- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs
@@ -196,17 +196,30 @@ namespace osu.Game.Overlays.Profile.Header.Components
}
}
- public string TooltipText => Statistics.Value?.Ranks.Global == null ? "" : $"#{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}";
+ public object TooltipContent
+ {
+ get
+ {
+ if (Statistics.Value?.Ranks.Global == null)
+ return null;
+
+ var days = ranked_days - ranks[dayIndex].Key + 1;
+
+ return new TooltipDisplayContent
+ {
+ Rank = $"#{ranks[dayIndex].Value:#,##0}",
+ Time = days == 0 ? "now" : $"{days} days ago"
+ };
+ }
+ }
public ITooltip GetCustomTooltip() => new RankGraphTooltip();
- public class RankGraphTooltip : VisibilityContainer, ITooltip
+ private class RankGraphTooltip : VisibilityContainer, ITooltip
{
private readonly OsuSpriteText globalRankingText, timeText;
private readonly Box background;
- public string TooltipText { get; set; }
-
public RankGraphTooltip()
{
AutoSizeAxes = Axes.Both;
@@ -260,11 +273,14 @@ namespace osu.Game.Overlays.Profile.Header.Components
background.Colour = colours.GreySeafoamDark;
}
- public void Refresh()
+ public bool SetContent(object content)
{
- var info = TooltipText.Split('|');
- globalRankingText.Text = info[0];
- timeText.Text = info[1] == "0" ? "now" : $"{info[1]} days ago";
+ if (!(content is TooltipDisplayContent info))
+ return false;
+
+ globalRankingText.Text = info.Rank;
+ timeText.Text = info.Time;
+ return true;
}
private bool instantMove = true;
@@ -284,5 +300,11 @@ namespace osu.Game.Overlays.Profile.Header.Components
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
}
+
+ private class TooltipDisplayContent
+ {
+ public string Rank;
+ public string Time;
+ }
}
}
diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
index 1b6c1c99a6..8a6b52b7ee 100644
--- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
+++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
@@ -46,8 +46,11 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
if (!s.OnlineBeatmapSetID.HasValue)
continue;
- var panel = new DirectGridPanel(s.ToBeatmapSet(Rulesets));
- ItemsContainer.Add(panel);
+ ItemsContainer.Add(new DirectGridPanel(s.ToBeatmapSet(Rulesets))
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ });
}
});
diff --git a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs
index 5ed546c62b..cf4e1c0dde 100644
--- a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs
+++ b/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs
@@ -124,14 +124,12 @@ namespace osu.Game.Overlays.Profile.Sections
private class ChevronIcon : SpriteIcon
{
- private const int bottom_margin = 2;
private const int icon_size = 8;
public ChevronIcon()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- Margin = new MarginPadding { Bottom = bottom_margin };
Size = new Vector2(icon_size);
Icon = FontAwesome.Solid.ChevronDown;
}
diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs
index 7f794e2927..5000156e97 100644
--- a/osu.Game/Overlays/SettingsSubPanel.cs
+++ b/osu.Game/Overlays/SettingsSubPanel.cs
@@ -57,7 +57,6 @@ namespace osu.Game.Overlays
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Y = -15,
Size = new Vector2(15),
Shadow = true,
Icon = FontAwesome.Solid.ChevronLeft
diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs
index 2b2b19b73a..d6b810366d 100644
--- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs
+++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs
@@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(80).Opacity(180),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0,
},
Flow = new FillFlowContainer
diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
index b286cbfb1d..36387bb00d 100644
--- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
+++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150).Opacity(180),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Depth = 2,
Alpha = 0,
});
diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs
index a4884dc2c1..6d876a77b1 100644
--- a/osu.Game/Overlays/Volume/MuteButton.cs
+++ b/osu.Game/Overlays/Volume/MuteButton.cs
@@ -65,16 +65,15 @@ namespace osu.Game.Overlays.Volume
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(20),
}
});
- Current.ValueChanged += muted =>
+ Current.BindValueChanged(muted =>
{
icon.Icon = muted.NewValue ? FontAwesome.Solid.VolumeMute : FontAwesome.Solid.VolumeUp;
- };
-
- Current.TriggerChange();
+ icon.Size = new Vector2(muted.NewValue ? 18 : 20);
+ icon.Margin = new MarginPadding { Right = muted.NewValue ? 2 : 0 };
+ }, true);
}
protected override bool OnHover(HoverEvent e)
diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs
index 2200caeb20..e85ebb5f3a 100644
--- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs
+++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@@ -57,7 +58,12 @@ namespace osu.Game.Rulesets.Edit
this.drawableRuleset = drawableRuleset;
InternalChild = drawableRuleset;
+ }
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ drawableRuleset.FrameStablePlayback = false;
Playfield.DisplayJudgements.Value = false;
}
diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
index c8858233aa..e47df6b473 100644
--- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
@@ -325,9 +325,6 @@ namespace osu.Game.Rulesets.Scoring
JudgedHits++;
- if (result.Type != HitResult.None)
- scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
-
if (result.Judgement.AffectsCombo)
{
switch (result.Type)
@@ -352,6 +349,9 @@ namespace osu.Game.Rulesets.Scoring
}
else
{
+ if (result.HasResult)
+ scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
+
baseScore += result.Judgement.NumericResultFor(result);
rollingMaxBaseScore += result.Judgement.MaxNumericResult;
}
@@ -371,9 +371,6 @@ namespace osu.Game.Rulesets.Scoring
JudgedHits--;
- if (result.Type != HitResult.None)
- scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
-
if (result.Judgement.IsBonus)
{
if (result.IsHit)
@@ -381,6 +378,9 @@ namespace osu.Game.Rulesets.Scoring
}
else
{
+ if (result.HasResult)
+ scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
+
baseScore -= result.Judgement.NumericResultFor(result);
rollingMaxBaseScore -= result.Judgement.MaxNumericResult;
}
diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs
index ac81fdc719..eb14bd1f24 100644
--- a/osu.Game/Rulesets/UI/DrawableRuleset.cs
+++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs
@@ -62,6 +62,15 @@ namespace osu.Game.Rulesets.UI
public override GameplayClock FrameStableClock => frameStabilityContainer.GameplayClock;
+ ///
+ /// Whether to enable frame-stable playback.
+ ///
+ internal bool FrameStablePlayback
+ {
+ get => frameStabilityContainer.FrameStablePlayback;
+ set => frameStabilityContainer.FrameStablePlayback = value;
+ }
+
///
/// Invoked when a has been applied by a .
///
diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
index 1cc56fff8b..05d3c02381 100644
--- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
+++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
@@ -24,6 +24,11 @@ namespace osu.Game.Rulesets.UI
///
public int MaxCatchUpFrames { get; set; } = 5;
+ ///
+ /// Whether to enable frame-stable playback.
+ ///
+ internal bool FrameStablePlayback = true;
+
[Cached]
public GameplayClock GameplayClock { get; }
@@ -113,7 +118,13 @@ namespace osu.Game.Rulesets.UI
try
{
- if (firstConsumption)
+ if (!FrameStablePlayback)
+ {
+ manualClock.CurrentTime = newProposedTime;
+ requireMoreUpdateLoops = false;
+ return;
+ }
+ else if (firstConsumption)
{
// On the first update, frame-stability seeking would result in unexpected/unwanted behaviour.
// Instead we perform an initial seek to the proposed time.
diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs
index 5bb1de7a38..88a2338b94 100644
--- a/osu.Game/Rulesets/UI/ModIcon.cs
+++ b/osu.Game/Rulesets/UI/ModIcon.cs
@@ -52,7 +52,6 @@ namespace osu.Game.Rulesets.UI
Anchor = Anchor.Centre,
Size = new Vector2(size),
Icon = OsuIcon.ModBg,
- Y = -6.5f,
Shadow = true,
},
modIcon = new SpriteIcon
diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
index 70c0cf623e..5854d66aa8 100644
--- a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
+++ b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
@@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Scale = new Vector2(0.5f),
X = 10,
Masking = true,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Child = new Box { RelativeSizeAxes = Axes.Both }
};
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
index c615656d60..0d16d8474b 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
@@ -360,7 +360,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.2f), Color4.White),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
new EquilateralTriangle
{
diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs
index badd1e0549..1bf25a2504 100644
--- a/osu.Game/Screens/Menu/Button.cs
+++ b/osu.Game/Screens/Menu/Button.cs
@@ -92,7 +92,7 @@ namespace osu.Game.Screens.Menu
{
EdgeSmoothness = new Vector2(1.5f, 0),
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs
index 27f3c9a45b..4d0f7ff87a 100644
--- a/osu.Game/Screens/Menu/IntroScreen.cs
+++ b/osu.Game/Screens/Menu/IntroScreen.cs
@@ -28,11 +28,18 @@ namespace osu.Game.Screens.Menu
private Bindable menuVoice;
+ private LeasedBindable beatmap;
+
+ public new Bindable Beatmap => beatmap;
+
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
{
+ // prevent user from changing beatmap while the intro is still runnning.
+ beatmap = base.Beatmap.BeginLease(false);
+
menuVoice = config.GetBindable(OsuSetting.MenuVoice);
seeya = audio.Samples.Get(@"seeya");
}
@@ -107,6 +114,8 @@ namespace osu.Game.Screens.Menu
protected void LoadMenu()
{
+ beatmap.Return();
+
DidLoadMenu = true;
this.Push(mainMenu);
}
diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs
index ba0d624959..db970dd76e 100644
--- a/osu.Game/Screens/Menu/IntroTriangles.cs
+++ b/osu.Game/Screens/Menu/IntroTriangles.cs
@@ -138,8 +138,8 @@ namespace osu.Game.Screens.Menu
private RulesetFlow rulesets;
private Container rulesetsScale;
- private Drawable logoContainerSecondary;
- private Drawable logoContainer;
+ private Container logoContainerSecondary;
+ private Drawable lazerLogo;
private GlitchingTriangles triangles;
@@ -158,7 +158,7 @@ namespace osu.Game.Screens.Menu
{
this.game = game;
- InternalChildren = new[]
+ InternalChildren = new Drawable[]
{
triangles = new GlitchingTriangles
{
@@ -191,7 +191,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Child = logoContainer = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4"))
+ Child = lazerLogo = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4"))
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -222,7 +222,7 @@ namespace osu.Game.Screens.Menu
const float scale_adjust = 0.8f;
rulesets.Hide();
- logoContainer.Hide();
+ lazerLogo.Hide();
background.Hide();
using (BeginAbsoluteSequence(0, true))
@@ -269,14 +269,17 @@ namespace osu.Game.Screens.Menu
rulesets.FadeOut();
// matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5
- logoContainer.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint);
+ lazerLogo.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint);
logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad);
}
using (BeginDelayedSequence(logo_2, true))
{
- logoContainer.FadeOut().OnComplete(_ =>
+ lazerLogo.FadeOut().OnComplete(_ =>
{
+ logoContainerSecondary.Remove(lazerLogo);
+ lazerLogo.Dispose(); // explicit disposal as we are pushing a new screen and the expire may not get run.
+
logo.FadeIn();
background.FadeIn();
@@ -296,7 +299,7 @@ namespace osu.Game.Screens.Menu
{
Colour = Color4.White;
RelativeSizeAxes = Axes.Both;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
}
protected override void LoadComplete()
@@ -399,11 +402,11 @@ namespace osu.Game.Screens.Menu
Origin = Anchor.Centre,
Colour = Color4.Black,
Size = new Vector2(size - 5),
- Blending = BlendingMode.None,
+ Blending = BlendingParameters.None,
});
}
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
CacheDrawnFrameBuffer = true;
}
}
diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs
index 39bda799b5..9d0a5cd05b 100644
--- a/osu.Game/Screens/Menu/LogoVisualisation.cs
+++ b/osu.Game/Screens/Menu/LogoVisualisation.cs
@@ -76,7 +76,7 @@ namespace osu.Game.Screens.Menu
public LogoVisualisation()
{
texture = Texture.WhitePixel;
- Blending = BlendingMode.Additive;
+ Blending = BlendingParameters.Additive;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs
index 95d0bf04b4..393964561c 100644
--- a/osu.Game/Screens/Menu/MenuSideFlashes.cs
+++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu
// align off-screen to make sure our edges don't become visible during parallax.
X = -box_width,
Alpha = 0,
- Blending = BlendingMode.Additive
+ Blending = BlendingParameters.Additive
},
rightBox = new Box
{
@@ -81,7 +81,7 @@ namespace osu.Game.Screens.Menu
Height = 1.5f,
X = box_width,
Alpha = 0,
- Blending = BlendingMode.Additive
+ Blending = BlendingParameters.Additive
}
};
diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs
index 479b3d80b6..0c5bf12bdb 100644
--- a/osu.Game/Screens/Menu/OsuLogo.cs
+++ b/osu.Game/Screens/Menu/OsuLogo.cs
@@ -124,7 +124,7 @@ namespace osu.Game.Screens.Menu
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Alpha = 0
}
}
@@ -185,7 +185,7 @@ namespace osu.Game.Screens.Menu
flashLayer = new Box
{
RelativeSizeAxes = Axes.Both,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs
index f3412d0be7..de6ece6a05 100644
--- a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs
+++ b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Screens.Multi.Match.Components
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.15f,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
});
}
diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs
index 5648dd997b..6c5854d17e 100644
--- a/osu.Game/Screens/ScreenWhiteBox.cs
+++ b/osu.Game/Screens/ScreenWhiteBox.cs
@@ -95,7 +95,7 @@ namespace osu.Game.Screens
Colour = getColourFor(GetType()),
Alpha = 0.2f,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
textContainer = new FillFlowContainer
{
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 7366fa8c17..23c581c6f9 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -24,7 +24,7 @@ using osu.Game.Screens.Select.Carousel;
namespace osu.Game.Screens.Select
{
- public class BeatmapCarousel : OsuScrollContainer
+ public class BeatmapCarousel : CompositeDrawable
{
private const float bleed_top = FilterControl.HEIGHT;
private const float bleed_bottom = Footer.HEIGHT;
@@ -61,6 +61,8 @@ namespace osu.Game.Screens.Select
///
public bool BeatmapSetsLoaded { get; private set; }
+ private readonly OsuScrollContainer scroll;
+
private IEnumerable beatmapSets => root.Children.OfType();
public IEnumerable BeatmapSets
@@ -110,13 +112,17 @@ namespace osu.Game.Screens.Select
public BeatmapCarousel()
{
root = new CarouselRoot(this);
- Child = new OsuContextMenuContainer
+ InternalChild = new OsuContextMenuContainer
{
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Child = scrollableContent = new Container
+ RelativeSizeAxes = Axes.Both,
+ Child = scroll = new CarouselScrollContainer
{
- RelativeSizeAxes = Axes.X,
+ Masking = false,
+ RelativeSizeAxes = Axes.Both,
+ Child = scrollableContent = new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ }
}
};
}
@@ -127,7 +133,7 @@ namespace osu.Game.Screens.Select
config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm);
config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled);
- RightClickScrollingEnabled.ValueChanged += enabled => RightMouseScrollbar = enabled.NewValue;
+ RightClickScrollingEnabled.ValueChanged += enabled => scroll.RightMouseScrollbar = enabled.NewValue;
RightClickScrollingEnabled.TriggerChange();
loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable());
@@ -351,12 +357,12 @@ namespace osu.Game.Screens.Select
///
/// The position of the lower visible bound with respect to the current scroll position.
///
- private float visibleBottomBound => Current + DrawHeight + bleed_bottom;
+ private float visibleBottomBound => scroll.Current + DrawHeight + bleed_bottom;
///
/// The position of the upper visible bound with respect to the current scroll position.
///
- private float visibleUpperBound => Current - bleed_top;
+ private float visibleUpperBound => scroll.Current - bleed_top;
public void FlushPendingFilterOperations()
{
@@ -628,7 +634,7 @@ namespace osu.Game.Screens.Select
private void updateScrollPosition()
{
- if (scrollTarget != null) ScrollTo(scrollTarget.Value);
+ if (scrollTarget != null) scroll.ScrollTo(scrollTarget.Value);
scrollPositionCache.Validate();
}
@@ -688,5 +694,35 @@ namespace osu.Game.Screens.Select
base.PerformSelection();
}
}
+
+ private class CarouselScrollContainer : OsuScrollContainer
+ {
+ private bool rightMouseScrollBlocked;
+
+ protected override bool OnMouseDown(MouseDownEvent e)
+ {
+ if (e.Button == MouseButton.Right)
+ {
+ // we need to block right click absolute scrolling when hovering a carousel item so context menus can display.
+ // this can be reconsidered when we have an alternative to right click scrolling.
+ if (GetContainingInputManager().HoveredDrawables.OfType().Any())
+ {
+ rightMouseScrollBlocked = true;
+ return false;
+ }
+ }
+
+ rightMouseScrollBlocked = false;
+ return base.OnMouseDown(e);
+ }
+
+ protected override bool OnDragStart(DragStartEvent e)
+ {
+ if (rightMouseScrollBlocked)
+ return false;
+
+ return base.OnDragStart(e);
+ }
+ }
}
}
diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
index a9e4eaa9b3..5f6307e3b4 100644
--- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs
+++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
@@ -402,31 +402,35 @@ namespace osu.Game.Screens.Select
}
}
- private class DifficultyColourBar : DifficultyColouredContainer
+ private class DifficultyColourBar : Container
{
+ private readonly BeatmapInfo beatmap;
+
public DifficultyColourBar(BeatmapInfo beatmap)
- : base(beatmap)
{
+ this.beatmap = beatmap;
}
[BackgroundDependencyLoader]
- private void load()
+ private void load(OsuColour colours)
{
const float full_opacity_ratio = 0.7f;
+ var difficultyColour = colours.ForDifficultyRating(beatmap.DifficultyRating);
+
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = AccentColour,
+ Colour = difficultyColour,
Width = full_opacity_ratio,
},
new Box
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
- Colour = AccentColour,
+ Colour = difficultyColour,
Alpha = 0.5f,
X = full_opacity_ratio,
Width = 1 - full_opacity_ratio,
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
index 0a20f2aa6d..fba7a328c1 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
@@ -82,7 +82,7 @@ namespace osu.Game.Screens.Select.Carousel
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
- new DifficultyIcon(beatmap)
+ new DifficultyIcon(beatmap, shouldShowTooltip: false)
{
Scale = new Vector2(1.8f),
},
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
index 4ceb82d4cc..0a8c61e3d2 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
@@ -19,6 +19,7 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
+using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
@@ -95,10 +96,11 @@ namespace osu.Game.Screens.Select.Carousel
TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 },
Status = beatmapSet.Status
},
- new FillFlowContainer
+ new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
- Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList()
+ Spacing = new Vector2(3),
+ ChildrenEnumerable = getDifficultyIcons(),
},
}
}
@@ -107,6 +109,17 @@ namespace osu.Game.Screens.Select.Carousel
};
}
+ private const int maximum_difficulty_icons = 18;
+
+ private IEnumerable getDifficultyIcons()
+ {
+ var beatmaps = ((CarouselBeatmapSet)Item).Beatmaps.ToList();
+
+ return beatmaps.Count > maximum_difficulty_icons
+ ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key))
+ : beatmaps.Select(b => new FilterableDifficultyIcon(b));
+ }
+
public MenuItem[] ContextMenuItems
{
get
@@ -204,5 +217,18 @@ namespace osu.Game.Screens.Select.Carousel
filtered.TriggerChange();
}
}
+
+ public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon
+ {
+ public FilterableGroupedDifficultyIcon(List items, RulesetInfo ruleset)
+ : base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White)
+ {
+ items.ForEach(item => item.Filtered.ValueChanged += _ =>
+ {
+ // for now, fade the whole group based on the ratio of hidden items.
+ this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100);
+ });
+ }
+ }
}
}
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs
index b906bd935c..6118191302 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs
@@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select.Carousel
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
},
}
};
diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
index a8b5bbbd00..ff9beafb23 100644
--- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
+++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs
@@ -121,7 +121,7 @@ namespace osu.Game.Screens.Select.Options
{
RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(1.5f, 0),
- Blending = BlendingMode.Additive,
+ Blending = BlendingParameters.Additive,
Colour = Color4.White,
Alpha = 0,
},
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 7dd934f91a..edb0e6deb8 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -157,7 +157,6 @@ namespace osu.Game.Screens.Select
},
Child = Carousel = new BeatmapCarousel
{
- Masking = false,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1 - wedged_container_size.X, 1),
Anchor = Anchor.CentreRight,
@@ -360,6 +359,7 @@ namespace osu.Game.Screens.Select
return;
beatmapNoDebounce = beatmap;
+
performUpdateSelected();
}
@@ -587,10 +587,18 @@ namespace osu.Game.Screens.Select
{
Track track = Beatmap.Value.Track;
- if ((!track.IsRunning || restart) && music?.IsUserPaused != true)
+ if (!track.IsRunning || restart)
{
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
- track.Restart();
+
+ if (music != null)
+ {
+ // use the global music controller (when available) to cancel a potential local user paused state.
+ music.SeekTo(track.RestartPoint);
+ music.Play();
+ }
+ else
+ track.Restart();
}
}
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 3eda76e40f..48310cf027 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -1,4 +1,4 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
@@ -11,10 +11,12 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
+using osu.Framework.Text;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
@@ -42,6 +44,8 @@ namespace osu.Game.Skinning
public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager)
: this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini")
{
+ // defaults should only be applied for non-beatmap skins (which are parsed via this constructor).
+ if (!Configuration.CustomColours.ContainsKey("SliderBall")) Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255);
}
private readonly bool hasHitCircle;
@@ -59,7 +63,7 @@ namespace osu.Game.Skinning
Samples = audioManager.GetSampleStore(storage);
Textures = new TextureStore(new TextureLoaderStore(storage));
- using (var testStream = storage.GetStream("hitcircle"))
+ using (var testStream = storage.GetStream("hitcircle@2x") ?? storage.GetStream("hitcircle"))
hasHitCircle |= testStream != null;
if (hasHitCircle)
@@ -75,8 +79,13 @@ namespace osu.Game.Skinning
Samples?.Dispose();
}
+ private const double default_frame_time = 1000 / 60d;
+
public override Drawable GetDrawableComponent(string componentName)
{
+ bool animatable = false;
+ bool looping = true;
+
switch (componentName)
{
case "Play/osu/cursor":
@@ -86,8 +95,20 @@ namespace osu.Game.Skinning
return null;
case "Play/osu/sliderball":
- if (GetTexture("sliderb") != null)
- return new LegacySliderBall();
+ var sliderBallContent = getAnimation("sliderb", true, true, "");
+
+ if (sliderBallContent != null)
+ {
+ var size = sliderBallContent.Size;
+
+ sliderBallContent.RelativeSizeAxes = Axes.Both;
+ sliderBallContent.Size = Vector2.One;
+
+ return new LegacySliderBall(sliderBallContent)
+ {
+ Size = size
+ };
+ }
return null;
@@ -97,26 +118,38 @@ namespace osu.Game.Skinning
return null;
+ case "Play/osu/sliderfollowcircle":
+ animatable = true;
+ break;
+
case "Play/Miss":
componentName = "hit0";
+ animatable = true;
+ looping = false;
break;
case "Play/Meh":
componentName = "hit50";
+ animatable = true;
+ looping = false;
break;
case "Play/Good":
componentName = "hit100";
+ animatable = true;
+ looping = false;
break;
case "Play/Great":
componentName = "hit300";
+ animatable = true;
+ looping = false;
break;
case "Play/osu/number-text":
return !hasFont(Configuration.HitCircleFont)
? null
- : new LegacySpriteText(Textures, Configuration.HitCircleFont)
+ : new LegacySpriteText(this, Configuration.HitCircleFont)
{
Scale = new Vector2(0.96f),
// Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size
@@ -124,25 +157,42 @@ namespace osu.Game.Skinning
};
}
- // temporary allowance is given for skins the fact that stable handles non-animatable items such as hitcircles (incorrectly)
- // by (incorrectly) displaying the first frame of animation rather than the non-animated version.
- // users have used this to "hide" certain elements like hit300.
- var texture = GetTexture($"{componentName}-0") ?? GetTexture(componentName);
-
- if (texture == null)
- return null;
-
- return new Sprite { Texture = texture };
+ return getAnimation(componentName, animatable, looping);
}
- public class LegacySliderBall : Sprite
+ private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-")
{
- [BackgroundDependencyLoader]
- private void load(ISkinSource skin)
+ Texture texture;
+
+ Texture getFrameTexture(int frame) => GetTexture($"{componentName}{animationSeparator}{frame}");
+
+ TextureAnimation animation = null;
+
+ if (animatable)
{
- Texture = skin.GetTexture("sliderb");
- Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White;
+ for (int i = 0;; i++)
+ {
+ if ((texture = getFrameTexture(i)) == null)
+ break;
+
+ if (animation == null)
+ animation = new TextureAnimation
+ {
+ DefaultFrameLength = default_frame_time,
+ Repeat = looping
+ };
+
+ animation.AddFrame(texture);
+ }
}
+
+ if (animation != null)
+ return animation;
+
+ if ((texture = GetTexture(componentName)) != null)
+ return new Sprite { Texture = texture };
+
+ return null;
}
public override Texture GetTexture(string componentName)
@@ -234,37 +284,43 @@ namespace osu.Game.Skinning
private class LegacySpriteText : OsuSpriteText
{
- private readonly TextureStore textures;
- private readonly string font;
+ private readonly LegacyGlyphStore glyphStore;
- public LegacySpriteText(TextureStore textures, string font)
+ public LegacySpriteText(ISkin skin, string font)
{
- this.textures = textures;
- this.font = font;
-
Shadow = false;
UseFullGlyphHeight = false;
+
+ Font = new FontUsage(font, OsuFont.DEFAULT_FONT_SIZE);
+ glyphStore = new LegacyGlyphStore(skin);
}
- protected override Texture GetTextureForCharacter(char c)
+ protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore);
+
+ private class LegacyGlyphStore : ITexturedGlyphLookupStore
{
- string textureName = $"{font}-{c}";
+ private readonly ISkin skin;
- // Approximate value that brings character sizing roughly in-line with stable
- float ratio = 36;
-
- var texture = textures.Get($"{textureName}@2x");
-
- if (texture == null)
+ public LegacyGlyphStore(ISkin skin)
{
- ratio = 18;
- texture = textures.Get(textureName);
+ this.skin = skin;
}
- if (texture != null)
- texture.ScaleAdjust = ratio;
+ public ITexturedCharacterGlyph Get(string fontName, char character)
+ {
+ var texture = skin.GetTexture($"{fontName}-{character}");
- return texture;
+ if (texture != null)
+ // Approximate value that brings character sizing roughly in-line with stable
+ texture.ScaleAdjust *= 18;
+
+ if (texture == null)
+ return null;
+
+ return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, null), texture, 1f / texture.ScaleAdjust);
+ }
+
+ public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character));
}
}
@@ -299,6 +355,37 @@ namespace osu.Game.Skinning
}
}
+ public class LegacySliderBall : CompositeDrawable
+ {
+ private readonly Drawable animationContent;
+
+ public LegacySliderBall(Drawable animationContent)
+ {
+ this.animationContent = animationContent;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(ISkinSource skin, DrawableHitObject drawableObject)
+ {
+ animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White;
+
+ InternalChildren = new[]
+ {
+ new Sprite
+ {
+ Texture = skin.GetTexture("sliderb-nd"),
+ Colour = new Color4(5, 5, 5, 255),
+ },
+ animationContent,
+ new Sprite
+ {
+ Texture = skin.GetTexture("sliderb-spec"),
+ Blending = BlendingParameters.Additive,
+ },
+ };
+ }
+ }
+
public class LegacyMainCirclePiece : CompositeDrawable
{
public LegacyMainCirclePiece()
diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs
index b1cc0436de..461ee762e9 100644
--- a/osu.Game/Storyboards/CommandTimelineGroup.cs
+++ b/osu.Game/Storyboards/CommandTimelineGroup.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Storyboards
public CommandTimeline Rotation = new CommandTimeline();
public CommandTimeline Colour = new CommandTimeline();
public CommandTimeline Alpha = new CommandTimeline();
- public CommandTimeline BlendingMode = new CommandTimeline();
+ public CommandTimeline BlendingParameters = new CommandTimeline();
public CommandTimeline FlipH = new CommandTimeline();
public CommandTimeline FlipV = new CommandTimeline();
@@ -35,7 +35,7 @@ namespace osu.Game.Storyboards
yield return Rotation;
yield return Colour;
yield return Alpha;
- yield return BlendingMode;
+ yield return BlendingParameters;
yield return FlipH;
yield return FlipV;
}
diff --git a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs
index 7e31e1135e..bbc55a336d 100644
--- a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs
+++ b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs
@@ -12,19 +12,19 @@ namespace osu.Game.Storyboards.Drawables
/// Adjusts after a delay.
///
/// A to which further transforms can be added.
- public static TransformSequence TransformBlendingMode(this T drawable, BlendingMode newValue, double delay = 0)
+ public static TransformSequence TransformBlendingMode(this T drawable, BlendingParameters newValue, double delay = 0)
where T : Drawable
- => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingMode(), newValue, delay));
+ => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingParameters(), newValue, delay));
}
- public class TransformBlendingMode : Transform
+ public class TransformBlendingParameters : Transform
{
- private BlendingMode valueAt(double time)
+ private BlendingParameters valueAt(double time)
=> time < EndTime ? StartValue : EndValue;
public override string TargetMember => nameof(Drawable.Blending);
protected override void Apply(Drawable d, double time) => d.Blending = valueAt(time);
- protected override void ReadIntoStartValue(Drawable d) => StartValue = d.Blending.Mode;
+ protected override void ReadIntoStartValue(Drawable d) => StartValue = d.Blending;
}
}
diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs
index 8f8ec22aae..37c3ff495f 100644
--- a/osu.Game/Storyboards/StoryboardSprite.cs
+++ b/osu.Game/Storyboards/StoryboardSprite.cs
@@ -69,7 +69,7 @@ namespace osu.Game.Storyboards
applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing));
applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing));
applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing));
- applyCommands(drawable, getCommands(g => g.BlendingMode, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false);
+ applyCommands(drawable, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false);
if (drawable is IFlippable flippable)
{
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index f5e4d4b1fb..4fe9119cef 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -14,9 +14,9 @@
-
-
-
+
+
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 63fa354418..82301549d7 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -117,10 +117,10 @@
-
-
-
-
+
+
+
+