1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:22:55 +08:00

Merge branch 'master' into add-spinner-bonus-score

This commit is contained in:
Salman Ahmed 2019-08-22 09:48:09 +03:00 committed by GitHub
commit f4f15cc803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 362 additions and 230 deletions

View File

@ -61,6 +61,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.816.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2019.821.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
AccentColour = Color4.Red, AccentColour = Color4.Red,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0.5f, Alpha = 0.5f,
Scale = new Vector2(1.333f) Scale = new Vector2(1.333f)
}); });

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
Anchor = Anchor.Centre; Anchor = Anchor.Centre;
Origin = Anchor.Centre; Origin = Anchor.Centre;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Colour = Color4.White.Opacity(0.9f); Colour = Color4.White.Opacity(0.9f);
} }

View File

@ -201,7 +201,7 @@ namespace osu.Game.Rulesets.Catch.UI
additive.Scale = Scale; additive.Scale = Scale;
additive.Colour = HyperDashing ? Color4.Red : Color4.White; additive.Colour = HyperDashing ? Color4.Red : Color4.White;
additive.RelativePositionAxes = RelativePositionAxes; additive.RelativePositionAxes = RelativePositionAxes;
additive.Blending = BlendingMode.Additive; additive.Blending = BlendingParameters.Additive;
AdditiveTarget.Add(additive); AdditiveTarget.Add(additive);

View File

@ -26,14 +26,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public BodyPiece() public BodyPiece()
{ {
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Children = new[] Children = new[]
{ {
Background = new Box { RelativeSizeAxes = Axes.Both }, Background = new Box { RelativeSizeAxes = Axes.Both },
Foreground = new BufferedContainer Foreground = new BufferedContainer
{ {
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
CacheDrawnFrameBuffer = true, CacheDrawnFrameBuffer = true,
Children = new Drawable[] Children = new Drawable[]

View File

@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
Name = "Top", Name = "Top",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.5f, Height = 0.5f,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha)) Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha))
}, },
new Box new Box
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
Origin = Anchor.BottomLeft, Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.5f, Height = 0.5f,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent) Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent)
} }
}; };

View File

@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
Name = "Background Gradient Overlay", Name = "Background Gradient Overlay",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.5f, Height = 0.5f,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0 Alpha = 0
} }
}; };

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -2,12 +2,12 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.IO; using System.Text.RegularExpressions;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Game.Skinning; using osu.Game.Skinning;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
@ -28,11 +28,11 @@ namespace osu.Game.Rulesets.Osu.Tests
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio) 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"); metricsSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), audio, true);
defaultSkin = getSkinFromResources(skins, "default_skin"); defaultSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore<byte[]>(dllStore, "Resources/default_skin"), audio, false);
specialSkin = getSkinFromResources(skins, "special_skin"); specialSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore<byte[]>(dllStore, "Resources/special_skin"), audio, true);
} }
public void SetContents(Func<Drawable> creationFunction) public void SetContents(Func<Drawable> creationFunction)
@ -43,23 +43,28 @@ namespace osu.Game.Rulesets.Osu.Tests
Cell(3).Child = new LocalSkinOverrideContainer(specialSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); 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<byte[]> storage, AudioManager audioManager, bool extrapolateAnimations)
: base(skin, storage, audioManager, "skin.ini")
{ {
var tempName = Path.GetTempFileName(); this.extrapolateAnimations = extrapolateAnimations;
}
File.Delete(tempName); public override Texture GetTexture(string componentName)
Directory.CreateDirectory(tempName); {
// 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) return base.GetTexture(componentName);
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);
} }
} }
} }

View File

@ -0,0 +1,34 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.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<Type> RequiredTypes => new[]
{
typeof(DrawableJudgement),
typeof(DrawableOsuJudgement)
};
public TestSceneDrawableJudgement()
{
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}));
}
}
}

View File

@ -10,7 +10,6 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Tests.Visual;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -27,83 +26,96 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests namespace osu.Game.Rulesets.Osu.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneSlider : OsuTestScene public class TestSceneSlider : SkinnableTestScene
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(Slider),
typeof(SliderTick),
typeof(SliderTailCircle),
typeof(SliderBall), typeof(SliderBall),
typeof(SliderBody), typeof(SliderBody),
typeof(SliderTick), typeof(SnakingSliderBody),
typeof(DrawableSlider), typeof(DrawableSlider),
typeof(DrawableSliderTick), typeof(DrawableSliderTick),
typeof(DrawableSliderTail),
typeof(DrawableSliderHead),
typeof(DrawableRepeatPoint), typeof(DrawableRepeatPoint),
typeof(DrawableOsuHitObject) typeof(DrawableOsuHitObject)
}; };
private readonly Container content; private Container content;
protected override Container<Drawable> Content => content;
protected override Container<Drawable> Content
{
get
{
if (content == null)
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
return content;
}
}
private int depthIndex; private int depthIndex;
public TestSceneSlider() 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("Slow Slider", () => SetContents(testSlowSpeed)); // slow long sliders take ages already so no repeat steps
AddStep("Medium Single", () => testSimpleMedium()); AddStep("Slow Short Slider", () => SetContents(() => testShortSlowSpeed()));
AddStep("Small Single", () => testSimpleSmall()); AddStep("Slow Short Slider 1 Repeats", () => SetContents(() => testShortSlowSpeed(1)));
AddStep("Big 1 Repeat", () => testSimpleBig(1)); AddStep("Slow Short Slider 2 Repeats", () => SetContents(() => testShortSlowSpeed(2)));
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", testSlowSpeed); // slow long sliders take ages already so no repeat steps AddStep("Fast Slider", () => SetContents(() => testHighSpeed()));
AddStep("Slow Short Slider", () => testShortSlowSpeed()); AddStep("Fast Slider 1 Repeat", () => SetContents(() => testHighSpeed(1)));
AddStep("Slow Short Slider 1 Repeats", () => testShortSlowSpeed(1)); AddStep("Fast Slider 2 Repeats", () => SetContents(() => testHighSpeed(2)));
AddStep("Slow Short Slider 2 Repeats", () => testShortSlowSpeed(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("Perfect Curve", () => SetContents(() => testPerfect()));
AddStep("Fast Slider 1 Repeat", () => testHighSpeed(1)); AddStep("Perfect Curve 1 Repeat", () => SetContents(() => testPerfect(1)));
AddStep("Fast Slider 2 Repeats", () => testHighSpeed(2)); AddStep("Perfect Curve 2 Repeats", () => SetContents(() => testPerfect(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", () => testPerfect()); AddStep("Linear Slider", () => SetContents(() => testLinear()));
AddStep("Perfect Curve 1 Repeat", () => testPerfect(1)); AddStep("Linear Slider 1 Repeat", () => SetContents(() => testLinear(1)));
AddStep("Perfect Curve 2 Repeats", () => testPerfect(2)); AddStep("Linear Slider 2 Repeats", () => SetContents(() => testLinear(2)));
AddStep("Linear Slider", () => testLinear()); AddStep("Bezier Slider", () => SetContents(() => testBezier()));
AddStep("Linear Slider 1 Repeat", () => testLinear(1)); AddStep("Bezier Slider 1 Repeat", () => SetContents(() => testBezier(1)));
AddStep("Linear Slider 2 Repeats", () => testLinear(2)); AddStep("Bezier Slider 2 Repeats", () => SetContents(() => testBezier(2)));
AddStep("Bezier Slider", () => testBezier()); AddStep("Linear Overlapping", () => SetContents(() => testLinearOverlapping()));
AddStep("Bezier Slider 1 Repeat", () => testBezier(1)); AddStep("Linear Overlapping 1 Repeat", () => SetContents(() => testLinearOverlapping(1)));
AddStep("Bezier Slider 2 Repeats", () => testBezier(2)); AddStep("Linear Overlapping 2 Repeats", () => SetContents(() => testLinearOverlapping(2)));
AddStep("Linear Overlapping", () => testLinearOverlapping()); AddStep("Catmull Slider", () => SetContents(() => testCatmull()));
AddStep("Linear Overlapping 1 Repeat", () => testLinearOverlapping(1)); AddStep("Catmull Slider 1 Repeat", () => SetContents(() => testCatmull(1)));
AddStep("Linear Overlapping 2 Repeats", () => testLinearOverlapping(2)); AddStep("Catmull Slider 2 Repeats", () => SetContents(() => testCatmull(2)));
AddStep("Catmull Slider", () => testCatmull()); AddStep("Big Single, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset()));
AddStep("Catmull Slider 1 Repeat", () => testCatmull(1)); AddStep("Big 1 Repeat, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset(1)));
AddStep("Catmull Slider 2 Repeats", () => testCatmull(2));
AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset()); AddStep("Distance Overflow", () => SetContents(() => testDistanceOverflow()));
AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1)); AddStep("Distance Overflow 1 Repeat", () => SetContents(() => testDistanceOverflow(1)));
AddStep("Distance Overflow", () => testDistanceOverflow());
AddStep("Distance Overflow 1 Repeat", () => 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 var slider = new Slider
{ {
@ -120,22 +132,22 @@ namespace osu.Game.Rulesets.Osu.Tests
StackHeight = 10 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 var slider = new Slider
{ {
@ -151,10 +163,10 @@ namespace osu.Game.Rulesets.Osu.Tests
StackHeight = stackHeight 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 var slider = new Slider
{ {
@ -170,12 +182,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats) 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 var slider = new Slider
{ {
@ -194,12 +206,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats) 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 var slider = new Slider
{ {
@ -217,12 +229,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats) 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 var slider = new Slider
{ {
@ -241,12 +253,12 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = createEmptySamples(repeats) 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<List<HitSampleInfo>>(); var repeatSamples = new List<List<HitSampleInfo>>();
for (int i = 0; i < repeats; i++) for (int i = 0; i < repeats; i++)
@ -267,7 +279,7 @@ namespace osu.Game.Rulesets.Osu.Tests
NodeSamples = repeatSamples NodeSamples = repeatSamples
}; };
addSlider(slider, 3, 1); return createDrawable(slider, 3, 1);
} }
private List<List<HitSampleInfo>> createEmptySamples(int repeats) private List<List<HitSampleInfo>> createEmptySamples(int repeats)
@ -278,7 +290,7 @@ namespace osu.Game.Rulesets.Osu.Tests
return repeatSamples; return repeatSamples;
} }
private void addSlider(Slider slider, float circleSize, double speedMultiplier) private Drawable createDrawable(Slider slider, float circleSize, double speedMultiplier)
{ {
var cpi = new ControlPointInfo(); var cpi = new ControlPointInfo();
cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier }); cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier });
@ -296,7 +308,7 @@ namespace osu.Game.Rulesets.Osu.Tests
drawable.OnNewResult += onNewResult; drawable.OnNewResult += onNewResult;
Add(drawable); return drawable;
} }
private float judgementOffsetDirection = 1; private float judgementOffsetDirection = 1;

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
Child = new Box Child = new Box
{ {
Size = new Vector2(width), Size = new Vector2(width),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Alpha = 0.5f, Alpha = 0.5f,

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Origin = Anchor.Centre; Origin = Anchor.Centre;
InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
new TrianglesPiece new TrianglesPiece
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0.5f, Alpha = 0.5f,
} }
}; };

View File

@ -17,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre; Anchor = Anchor.Centre;
Origin = Anchor.Centre; Origin = Anchor.Centre;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Alpha = 0; Alpha = 0;
Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece
{ {
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Alpha = 0.2f, Alpha = 0.2f,
}, s => s.GetTexture("Play/osu/hitcircle") == null); }, s => s.GetTexture("Play/osu/hitcircle") == null);

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre; Anchor = Anchor.Centre;
Origin = Anchor.Centre; Origin = Anchor.Centre;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Alpha = 0; Alpha = 0;
Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Texture = textures.Get(name), Texture = textures.Get(name),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0.5f Alpha = 0.5f
}, s => s.GetTexture("Play/osu/hitcircle") == null); }, s => s.GetTexture("Play/osu/hitcircle") == null);
} }

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.drawableSlider = drawableSlider; this.drawableSlider = drawableSlider;
this.slider = slider; this.slider = slider;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Origin = Anchor.Centre; Origin = Anchor.Centre;
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
@ -55,7 +55,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Child = new Container Child = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
// TODO: support skin filename animation (sliderb0, sliderb1...)
Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()), 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; return action == OsuAction.LeftButton || action == OsuAction.RightButton;
} }
private Vector2? lastPosition;
public void UpdateProgress(double completionProgress) 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 private class FollowCircleContainer : Container
@ -190,7 +200,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Masking = true, Masking = true,
BorderThickness = 5, BorderThickness = 5,
BorderColour = Color4.Orange, BorderColour = Color4.Orange,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Child = new Box Child = new Box
{ {
Colour = Color4.Orange, Colour = Color4.Orange,

View File

@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Origin = Anchor.Centre, Origin = Anchor.Centre,
Alpha = 0, Alpha = 0,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Masking = true, Masking = true,
Children = new[] Children = new[]
{ {
@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Masking = true, Masking = true,
BorderThickness = target_ring_thick_border, BorderThickness = target_ring_thick_border,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Children = new Drawable[] Children = new Drawable[]
{ {
new Box new Box

View File

@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.White, Colour = Color4.White,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0, Alpha = 0,
AlwaysPresent = true AlwaysPresent = true
} }

View File

@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Alpha = 0, Alpha = 0,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
centre = new Sprite centre = new Sprite
{ {
@ -124,7 +124,7 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f), Size = new Vector2(0.7f),
Alpha = 0, Alpha = 0,
Blending = BlendingMode.Additive Blending = BlendingParameters.Additive
} }
}; };
} }

View File

@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
HitTarget = new HitTarget HitTarget = new HitTarget
{ {
@ -127,14 +127,14 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive Blending = BlendingParameters.Additive
}, },
judgementContainer = new JudgementContainer<DrawableTaikoJudgement> judgementContainer = new JudgementContainer<DrawableTaikoJudgement>
{ {
Name = "Judgements", Name = "Judgements",
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive Blending = BlendingParameters.Additive
}, },
} }
}, },

View File

@ -249,7 +249,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Size = new Vector2(50); Size = new Vector2(50);
Masking = true; Masking = true;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
Alpha = 0.5f; Alpha = 0.5f;
Child = new Box { RelativeSizeAxes = Axes.Both }; Child = new Box { RelativeSizeAxes = Axes.Both };

View File

@ -125,7 +125,7 @@ namespace osu.Game.Tournament.Components
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Gray, Colour = Color4.Gray,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0, Alpha = 0,
}, },
}); });

View File

@ -86,11 +86,6 @@ namespace osu.Game.Beatmaps.Drawables
private readonly FillFlowContainer difficultyFlow; private readonly FillFlowContainer difficultyFlow;
public string TooltipText
{
set { }
}
public DifficultyIconTooltip() public DifficultyIconTooltip()
{ {
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
@ -168,10 +163,6 @@ namespace osu.Game.Beatmaps.Drawables
return true; return true;
} }
public void Refresh()
{
}
public void Move(Vector2 pos) => Position = pos; public void Move(Vector2 pos) => Position = pos;
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);

View File

@ -246,7 +246,7 @@ namespace osu.Game.Beatmaps.Formats
switch (type) switch (type)
{ {
case "A": 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; break;
case "H": case "H":

View File

@ -15,6 +15,7 @@ using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers namespace osu.Game.Graphics.Containers
{ {
[Cached(typeof(IPreviewTrackOwner))]
public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction> public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler<GlobalAction>
{ {
private SampleChannel samplePopIn; private SampleChannel samplePopIn;
@ -38,13 +39,6 @@ namespace osu.Game.Graphics.Containers
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All); protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IPreviewTrackOwner>(this);
return dependencies;
}
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(AudioManager audio) private void load(AudioManager audio)
{ {

View File

@ -98,7 +98,7 @@ namespace osu.Game.Graphics.Containers
public OsuScrollbar(Direction scrollDir) public OsuScrollbar(Direction scrollDir)
: base(scrollDir) : base(scrollDir)
{ {
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
CornerRadius = 5; CornerRadius = 5;

View File

@ -150,7 +150,7 @@ namespace osu.Game.Graphics.Cursor
}, },
AdditiveLayer = new Sprite AdditiveLayer = new Sprite
{ {
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = colour.Pink, Colour = colour.Pink,
Alpha = 0, Alpha = 0,
Texture = textures.Get(@"Cursor/menu-cursor-additive"), Texture = textures.Get(@"Cursor/menu-cursor-additive"),

View File

@ -56,7 +56,7 @@ namespace osu.Game.Graphics.Sprites
BlurSigma = new Vector2(4), BlurSigma = new Vector2(4),
CacheDrawnFrameBuffer = true, CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Size = new Vector2(3f), Size = new Vector2(3f),
Children = new[] Children = new[]
{ {

View File

@ -254,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.Add(flash); colourContainer.Add(flash);
flash.Colour = ButtonColour; flash.Colour = ButtonColour;
flash.Blending = BlendingMode.Additive; flash.Blending = BlendingParameters.Additive;
flash.Alpha = 0.3f; flash.Alpha = 0.3f;
flash.FadeOutFromOne(click_duration); flash.FadeOutFromOne(click_duration);
flash.Expire(); flash.Expire();

View File

@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = HoverColour, Colour = HoverColour,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0, Alpha = 0,
}, },
} }

View File

@ -39,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface
hover = new Box hover = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = Color4.White.Opacity(0.1f), Colour = Color4.White.Opacity(0.1f),
Alpha = 0, Alpha = 0,
Depth = -1 Depth = -1

View File

@ -296,15 +296,6 @@ namespace osu.Game.Overlays.Profile.Header.Components
this.MoveTo(pos, 200, Easing.OutQuint); this.MoveTo(pos, 200, Easing.OutQuint);
} }
public void Refresh()
{
}
public string TooltipText
{
set => throw new InvalidOperationException();
}
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);

View File

@ -57,7 +57,6 @@ namespace osu.Game.Overlays
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Y = -15,
Size = new Vector2(15), Size = new Vector2(15),
Shadow = true, Shadow = true,
Icon = FontAwesome.Solid.ChevronLeft Icon = FontAwesome.Solid.ChevronLeft

View File

@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(80).Opacity(180), Colour = OsuColour.Gray(80).Opacity(180),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0, Alpha = 0,
}, },
Flow = new FillFlowContainer Flow = new FillFlowContainer

View File

@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Toolbar
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150).Opacity(180), Colour = OsuColour.Gray(150).Opacity(180),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Depth = 2, Depth = 2,
Alpha = 0, Alpha = 0,
}); });

View File

@ -325,9 +325,6 @@ namespace osu.Game.Rulesets.Scoring
JudgedHits++; JudgedHits++;
if (result.Type != HitResult.None)
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
if (result.Judgement.AffectsCombo) if (result.Judgement.AffectsCombo)
{ {
switch (result.Type) switch (result.Type)
@ -352,6 +349,9 @@ namespace osu.Game.Rulesets.Scoring
} }
else else
{ {
if (result.HasResult)
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
baseScore += result.Judgement.NumericResultFor(result); baseScore += result.Judgement.NumericResultFor(result);
rollingMaxBaseScore += result.Judgement.MaxNumericResult; rollingMaxBaseScore += result.Judgement.MaxNumericResult;
} }
@ -371,9 +371,6 @@ namespace osu.Game.Rulesets.Scoring
JudgedHits--; JudgedHits--;
if (result.Type != HitResult.None)
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
if (result.Judgement.IsBonus) if (result.Judgement.IsBonus)
{ {
if (result.IsHit) if (result.IsHit)
@ -381,6 +378,9 @@ namespace osu.Game.Rulesets.Scoring
} }
else else
{ {
if (result.HasResult)
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
baseScore -= result.Judgement.NumericResultFor(result); baseScore -= result.Judgement.NumericResultFor(result);
rollingMaxBaseScore -= result.Judgement.MaxNumericResult; rollingMaxBaseScore -= result.Judgement.MaxNumericResult;
} }

View File

@ -52,7 +52,6 @@ namespace osu.Game.Rulesets.UI
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Size = new Vector2(size), Size = new Vector2(size),
Icon = OsuIcon.ModBg, Icon = OsuIcon.ModBg,
Y = -6.5f,
Shadow = true, Shadow = true,
}, },
modIcon = new SpriteIcon modIcon = new SpriteIcon

View File

@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Scale = new Vector2(0.5f), Scale = new Vector2(0.5f),
X = 10, X = 10,
Masking = true, Masking = true,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Child = new Box { RelativeSizeAxes = Axes.Both } Child = new Box { RelativeSizeAxes = Axes.Both }
}; };
} }

View File

@ -360,7 +360,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.2f), Color4.White), Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.2f), Color4.White),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
new EquilateralTriangle new EquilateralTriangle
{ {

View File

@ -92,7 +92,7 @@ namespace osu.Game.Screens.Menu
{ {
EdgeSmoothness = new Vector2(1.5f, 0), EdgeSmoothness = new Vector2(1.5f, 0),
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = Color4.White, Colour = Color4.White,
Alpha = 0, Alpha = 0,
}, },

View File

@ -28,11 +28,18 @@ namespace osu.Game.Screens.Menu
private Bindable<bool> menuVoice; private Bindable<bool> menuVoice;
private LeasedBindable<WorkingBeatmap> beatmap;
public new Bindable<WorkingBeatmap> Beatmap => beatmap;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack(); protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) 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<bool>(OsuSetting.MenuVoice); menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
seeya = audio.Samples.Get(@"seeya"); seeya = audio.Samples.Get(@"seeya");
} }
@ -107,6 +114,8 @@ namespace osu.Game.Screens.Menu
protected void LoadMenu() protected void LoadMenu()
{ {
beatmap.Return();
DidLoadMenu = true; DidLoadMenu = true;
this.Push(mainMenu); this.Push(mainMenu);
} }

View File

@ -296,7 +296,7 @@ namespace osu.Game.Screens.Menu
{ {
Colour = Color4.White; Colour = Color4.White;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -399,11 +399,11 @@ namespace osu.Game.Screens.Menu
Origin = Anchor.Centre, Origin = Anchor.Centre,
Colour = Color4.Black, Colour = Color4.Black,
Size = new Vector2(size - 5), Size = new Vector2(size - 5),
Blending = BlendingMode.None, Blending = BlendingParameters.None,
}); });
} }
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
CacheDrawnFrameBuffer = true; CacheDrawnFrameBuffer = true;
} }
} }

View File

@ -76,7 +76,7 @@ namespace osu.Game.Screens.Menu
public LogoVisualisation() public LogoVisualisation()
{ {
texture = Texture.WhitePixel; texture = Texture.WhitePixel;
Blending = BlendingMode.Additive; Blending = BlendingParameters.Additive;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu
// align off-screen to make sure our edges don't become visible during parallax. // align off-screen to make sure our edges don't become visible during parallax.
X = -box_width, X = -box_width,
Alpha = 0, Alpha = 0,
Blending = BlendingMode.Additive Blending = BlendingParameters.Additive
}, },
rightBox = new Box rightBox = new Box
{ {
@ -81,7 +81,7 @@ namespace osu.Game.Screens.Menu
Height = 1.5f, Height = 1.5f,
X = box_width, X = box_width,
Alpha = 0, Alpha = 0,
Blending = BlendingMode.Additive Blending = BlendingParameters.Additive
} }
}; };

View File

@ -124,7 +124,7 @@ namespace osu.Game.Screens.Menu
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Alpha = 0 Alpha = 0
} }
} }
@ -185,7 +185,7 @@ namespace osu.Game.Screens.Menu
flashLayer = new Box flashLayer = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = Color4.White, Colour = Color4.White,
Alpha = 0, Alpha = 0,
}, },

View File

@ -31,7 +31,7 @@ namespace osu.Game.Screens.Multi.Match.Components
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Alpha = 0.15f, Alpha = 0.15f,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
}); });
} }

View File

@ -95,7 +95,7 @@ namespace osu.Game.Screens
Colour = getColourFor(GetType()), Colour = getColourFor(GetType()),
Alpha = 0.2f, Alpha = 0.2f,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
textContainer = new FillFlowContainer textContainer = new FillFlowContainer
{ {

View File

@ -98,6 +98,7 @@ namespace osu.Game.Screens.Select.Carousel
new FillFlowContainer<FilterableDifficultyIcon> new FillFlowContainer<FilterableDifficultyIcon>
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Spacing = new Vector2(3),
Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList() Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList()
}, },
} }

View File

@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Alpha = 0, Alpha = 0,
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
}, },
} }
}; };

View File

@ -121,7 +121,7 @@ namespace osu.Game.Screens.Select.Options
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(1.5f, 0), EdgeSmoothness = new Vector2(1.5f, 0),
Blending = BlendingMode.Additive, Blending = BlendingParameters.Additive,
Colour = Color4.White, Colour = Color4.White,
Alpha = 0, Alpha = 0,
}, },

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
@ -11,10 +11,12 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Text;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
@ -42,6 +44,8 @@ namespace osu.Game.Skinning
public LegacySkin(SkinInfo skin, IResourceStore<byte[]> storage, AudioManager audioManager) public LegacySkin(SkinInfo skin, IResourceStore<byte[]> storage, AudioManager audioManager)
: this(skin, new LegacySkinResourceStore<SkinFileInfo>(skin, storage), audioManager, "skin.ini") : this(skin, new LegacySkinResourceStore<SkinFileInfo>(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; private readonly bool hasHitCircle;
@ -59,7 +63,7 @@ namespace osu.Game.Skinning
Samples = audioManager.GetSampleStore(storage); Samples = audioManager.GetSampleStore(storage);
Textures = new TextureStore(new TextureLoaderStore(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; hasHitCircle |= testStream != null;
if (hasHitCircle) if (hasHitCircle)
@ -75,8 +79,13 @@ namespace osu.Game.Skinning
Samples?.Dispose(); Samples?.Dispose();
} }
private const double default_frame_time = 1000 / 60d;
public override Drawable GetDrawableComponent(string componentName) public override Drawable GetDrawableComponent(string componentName)
{ {
bool animatable = false;
bool looping = true;
switch (componentName) switch (componentName)
{ {
case "Play/osu/cursor": case "Play/osu/cursor":
@ -86,8 +95,20 @@ namespace osu.Game.Skinning
return null; return null;
case "Play/osu/sliderball": case "Play/osu/sliderball":
if (GetTexture("sliderb") != null) var sliderBallContent = getAnimation("sliderb", true, true, "");
return new LegacySliderBall();
if (sliderBallContent != null)
{
var size = sliderBallContent.Size;
sliderBallContent.RelativeSizeAxes = Axes.Both;
sliderBallContent.Size = Vector2.One;
return new LegacySliderBall(sliderBallContent)
{
Size = size
};
}
return null; return null;
@ -97,26 +118,38 @@ namespace osu.Game.Skinning
return null; return null;
case "Play/osu/sliderfollowcircle":
animatable = true;
break;
case "Play/Miss": case "Play/Miss":
componentName = "hit0"; componentName = "hit0";
animatable = true;
looping = false;
break; break;
case "Play/Meh": case "Play/Meh":
componentName = "hit50"; componentName = "hit50";
animatable = true;
looping = false;
break; break;
case "Play/Good": case "Play/Good":
componentName = "hit100"; componentName = "hit100";
animatable = true;
looping = false;
break; break;
case "Play/Great": case "Play/Great":
componentName = "hit300"; componentName = "hit300";
animatable = true;
looping = false;
break; break;
case "Play/osu/number-text": case "Play/osu/number-text":
return !hasFont(Configuration.HitCircleFont) return !hasFont(Configuration.HitCircleFont)
? null ? null
: new LegacySpriteText(Textures, Configuration.HitCircleFont) : new LegacySpriteText(this, Configuration.HitCircleFont)
{ {
Scale = new Vector2(0.96f), 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 // 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) return getAnimation(componentName, animatable, looping);
// 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 };
} }
public class LegacySliderBall : Sprite private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-")
{ {
[BackgroundDependencyLoader] Texture texture;
private void load(ISkinSource skin)
Texture getFrameTexture(int frame) => GetTexture($"{componentName}{animationSeparator}{frame}");
TextureAnimation animation = null;
if (animatable)
{ {
Texture = skin.GetTexture("sliderb"); for (int i = 0;; i++)
Colour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; {
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) public override Texture GetTexture(string componentName)
@ -234,37 +284,43 @@ namespace osu.Game.Skinning
private class LegacySpriteText : OsuSpriteText private class LegacySpriteText : OsuSpriteText
{ {
private readonly TextureStore textures; private readonly LegacyGlyphStore glyphStore;
private readonly string font;
public LegacySpriteText(TextureStore textures, string font) public LegacySpriteText(ISkin skin, string font)
{ {
this.textures = textures;
this.font = font;
Shadow = false; Shadow = false;
UseFullGlyphHeight = 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 public LegacyGlyphStore(ISkin skin)
float ratio = 36;
var texture = textures.Get($"{textureName}@2x");
if (texture == null)
{ {
ratio = 18; this.skin = skin;
texture = textures.Get(textureName);
} }
if (texture != null) public ITexturedCharacterGlyph Get(string fontName, char character)
texture.ScaleAdjust = ratio; {
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<ITexturedCharacterGlyph> 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<SkinConfiguration, Color4?>(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 class LegacyMainCirclePiece : CompositeDrawable
{ {
public LegacyMainCirclePiece() public LegacyMainCirclePiece()

View File

@ -20,7 +20,7 @@ namespace osu.Game.Storyboards
public CommandTimeline<float> Rotation = new CommandTimeline<float>(); public CommandTimeline<float> Rotation = new CommandTimeline<float>();
public CommandTimeline<Color4> Colour = new CommandTimeline<Color4>(); public CommandTimeline<Color4> Colour = new CommandTimeline<Color4>();
public CommandTimeline<float> Alpha = new CommandTimeline<float>(); public CommandTimeline<float> Alpha = new CommandTimeline<float>();
public CommandTimeline<BlendingMode> BlendingMode = new CommandTimeline<BlendingMode>(); public CommandTimeline<BlendingParameters> BlendingParameters = new CommandTimeline<BlendingParameters>();
public CommandTimeline<bool> FlipH = new CommandTimeline<bool>(); public CommandTimeline<bool> FlipH = new CommandTimeline<bool>();
public CommandTimeline<bool> FlipV = new CommandTimeline<bool>(); public CommandTimeline<bool> FlipV = new CommandTimeline<bool>();
@ -35,7 +35,7 @@ namespace osu.Game.Storyboards
yield return Rotation; yield return Rotation;
yield return Colour; yield return Colour;
yield return Alpha; yield return Alpha;
yield return BlendingMode; yield return BlendingParameters;
yield return FlipH; yield return FlipH;
yield return FlipV; yield return FlipV;
} }

View File

@ -12,19 +12,19 @@ namespace osu.Game.Storyboards.Drawables
/// Adjusts <see cref="Drawable.Blending"/> after a delay. /// Adjusts <see cref="Drawable.Blending"/> after a delay.
/// </summary> /// </summary>
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns> /// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
public static TransformSequence<T> TransformBlendingMode<T>(this T drawable, BlendingMode newValue, double delay = 0) public static TransformSequence<T> TransformBlendingMode<T>(this T drawable, BlendingParameters newValue, double delay = 0)
where T : Drawable where T : Drawable
=> drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingMode(), newValue, delay)); => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingParameters(), newValue, delay));
} }
public class TransformBlendingMode : Transform<BlendingMode, Drawable> public class TransformBlendingParameters : Transform<BlendingParameters, Drawable>
{ {
private BlendingMode valueAt(double time) private BlendingParameters valueAt(double time)
=> time < EndTime ? StartValue : EndValue; => time < EndTime ? StartValue : EndValue;
public override string TargetMember => nameof(Drawable.Blending); public override string TargetMember => nameof(Drawable.Blending);
protected override void Apply(Drawable d, double time) => d.Blending = valueAt(time); 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;
} }
} }

View File

@ -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.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.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.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) if (drawable is IFlippable flippable)
{ {

View File

@ -15,8 +15,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.816.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.821.0" />
<PackageReference Include="SharpCompress" Version="0.23.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />

View File

@ -118,9 +118,9 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.816.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.821.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.816.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2019.821.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />