1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Merge branch 'master' into argon-spinner

This commit is contained in:
Dean Herbert 2022-09-23 14:22:53 +09:00 committed by GitHub
commit a94b4e402e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 355 additions and 14 deletions

View File

@ -52,7 +52,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.916.1" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2022.922.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. --> <!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->

View File

@ -21,7 +21,6 @@ using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
using osuTK; using osuTK;
@ -250,11 +249,9 @@ namespace osu.Game.Rulesets.Catch.Tests
[Test] [Test]
public void TestHitLightingColour() public void TestHitLightingColour()
{ {
var fruitColour = SkinConfiguration.DefaultComboColours[1];
AddStep("enable hit lighting", () => config.SetValue(OsuSetting.HitLighting, true)); AddStep("enable hit lighting", () => config.SetValue(OsuSetting.HitLighting, true));
AddStep("catch fruit", () => attemptCatch(new Fruit())); AddStep("catch fruit", () => attemptCatch(new Fruit()));
AddAssert("correct hit lighting colour", () => AddAssert("correct hit lighting colour", () => catcher.ChildrenOfType<HitExplosion>().First()?.Entry?.ObjectColour == this.ChildrenOfType<DrawableCatchHitObject>().First().AccentColour.Value);
catcher.ChildrenOfType<HitExplosion>().First()?.Entry?.ObjectColour == fruitColour);
} }
[Test] [Test]

View File

@ -0,0 +1,102 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests.Mods
{
public class TestSceneOsuModRandom : OsuModTestScene
{
[TestCase(1)]
[TestCase(7)]
[TestCase(10)]
public void TestDefaultBeatmap(float angleSharpness) => CreateModTest(new ModTestData
{
Mod = new OsuModRandom
{
AngleSharpness = { Value = angleSharpness }
},
Autoplay = true,
PassCondition = () => true
});
[TestCase(1)]
[TestCase(7)]
[TestCase(10)]
public void TestJumpBeatmap(float angleSharpness) => CreateModTest(new ModTestData
{
Mod = new OsuModRandom
{
AngleSharpness = { Value = angleSharpness }
},
Beatmap = jumpBeatmap,
Autoplay = true,
PassCondition = () => true
});
[TestCase(1)]
[TestCase(7)]
[TestCase(10)]
public void TestStreamBeatmap(float angleSharpness) => CreateModTest(new ModTestData
{
Mod = new OsuModRandom
{
AngleSharpness = { Value = angleSharpness }
},
Beatmap = streamBeatmap,
Autoplay = true,
PassCondition = () => true
});
private OsuBeatmap jumpBeatmap =>
createHitCircleBeatmap(new[] { 100, 200, 300, 400 }, 8, 300, 2 * 300);
private OsuBeatmap streamBeatmap =>
createHitCircleBeatmap(new[] { 10, 20, 30, 40, 50, 60, 70, 80 }, 16, 150, 4 * 150);
private OsuBeatmap createHitCircleBeatmap(IEnumerable<int> spacings, int objectsPerSpacing, int interval, int beatLength)
{
var controlPointInfo = new ControlPointInfo();
controlPointInfo.Add(0, new TimingControlPoint
{
Time = 0,
BeatLength = beatLength
});
var beatmap = new OsuBeatmap
{
BeatmapInfo = new BeatmapInfo
{
StackLeniency = 0,
Difficulty = new BeatmapDifficulty
{
ApproachRate = 8.5f
}
},
ControlPointInfo = controlPointInfo
};
foreach (int spacing in spacings)
{
for (int i = 0; i < objectsPerSpacing; i++)
{
beatmap.HitObjects.Add(new HitCircle
{
StartTime = interval * beatmap.HitObjects.Count,
Position = beatmap.HitObjects.Count % 2 == 0 ? Vector2.Zero : new Vector2(spacing, 0),
NewCombo = i == 0
});
}
}
return beatmap;
}
}
}

View File

@ -0,0 +1,80 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
public class ArgonCursor : OsuCursorSprite
{
public ArgonCursor()
{
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
InternalChildren = new[]
{
ExpandTarget = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = 6,
BorderColour = ColourInfo.GradientVertical(Colour4.FromHex("FC618F"), Colour4.FromHex("BB1A41")),
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.4f,
Colour = Colour4.FromHex("FC618F").Darken(0.6f),
},
new CircularContainer
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = 2,
BorderColour = Color4.White.Opacity(0.8f),
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true,
},
},
},
},
},
new Circle
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Scale = new Vector2(0.2f),
Colour = new Color4(255, 255, 255, 255),
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Radius = 20,
Colour = new Color4(171, 255, 255, 100),
},
},
};
}
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osuTK;
namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
public class ArgonCursorTrail : CursorTrail
{
protected override float IntervalMultiplier => 0.4f;
protected override float FadeExponent => 4;
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(@"Cursor/cursortrail");
Scale = new Vector2(0.8f / Texture.ScaleAdjust);
Blending = BlendingParameters.Additive;
Alpha = 0.8f;
}
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osuTK;
namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
public class ArgonFollowPoint : CompositeDrawable
{
public ArgonFollowPoint()
{
Blending = BlendingParameters.Additive;
Colour = ColourInfo.GradientVertical(Colour4.FromHex("FC618F"), Colour4.FromHex("BB1A41"));
AutoSizeAxes = Axes.Both;
InternalChildren = new Drawable[]
{
new SpriteIcon
{
Icon = FontAwesome.Solid.ChevronRight,
Size = new Vector2(8),
Colour = OsuColour.Gray(0.2f),
},
new SpriteIcon
{
Icon = FontAwesome.Solid.ChevronRight,
Size = new Vector2(8),
X = 4,
},
};
}
}
}

View File

@ -133,7 +133,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
const double fade_out_time = 800; const double fade_out_time = 800;
const double flash_in_duration = 150; const double flash_in_duration = 150;
const double resize_duration = 300; const double resize_duration = 400;
const float shrink_size = 0.8f; const float shrink_size = 0.8f;
@ -165,13 +165,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
// The outer gradient is resize with a slight delay from the border. // The outer gradient is resize with a slight delay from the border.
// This is to give it a bomb-like effect, with the border "triggering" its animation when getting close. // This is to give it a bomb-like effect, with the border "triggering" its animation when getting close.
using (BeginDelayedSequence(flash_in_duration / 12)) using (BeginDelayedSequence(flash_in_duration / 12))
{
outerGradient.ResizeTo(outerGradient.Size * shrink_size, resize_duration, Easing.OutElasticHalf); outerGradient.ResizeTo(outerGradient.Size * shrink_size, resize_duration, Easing.OutElasticHalf);
outerGradient
.FadeColour(Color4.White, 80)
.Then()
.FadeOut(flash_in_duration);
}
// The flash layer starts white to give the wanted brightness, but is almost immediately // The flash layer starts white to give the wanted brightness, but is almost immediately
// recoloured to the accent colour. This would more correctly be done with two layers (one for the initial flash) // recoloured to the accent colour. This would more correctly be done with two layers (one for the initial flash)
// but works well enough with the colour fade. // but works well enough with the colour fade.
flash.FadeTo(1, flash_in_duration, Easing.OutQuint); flash.FadeTo(1, flash_in_duration, Easing.OutQuint);
flash.FlashColour(Color4.White, flash_in_duration, Easing.OutQuint); flash.FlashColour(accentColour.Value, fade_out_time, Easing.OutQuint);
this.FadeOut(fade_out_time, Easing.OutQuad); this.FadeOut(fade_out_time, Easing.OutQuad);
break; break;

View File

@ -47,6 +47,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
case OsuSkinComponents.ReverseArrow: case OsuSkinComponents.ReverseArrow:
return new ArgonReverseArrow(); return new ArgonReverseArrow();
case OsuSkinComponents.FollowPoint:
return new ArgonFollowPoint();
case OsuSkinComponents.Cursor:
return new ArgonCursor();
case OsuSkinComponents.CursorTrail:
return new ArgonCursorTrail();
} }
break; break;

View File

@ -24,6 +24,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Screens; using osu.Framework.Screens;
@ -187,7 +188,8 @@ namespace osu.Game
{ {
this.args = args; this.args = args;
forwardLoggedErrorsToNotifications(); forwardGeneralLogsToNotifications();
forwardTabletLogsToNotifications();
SentryLogger = new SentryLogger(this); SentryLogger = new SentryLogger(this);
} }
@ -994,7 +996,7 @@ namespace osu.Game
overlay.Depth = (float)-Clock.CurrentTime; overlay.Depth = (float)-Clock.CurrentTime;
} }
private void forwardLoggedErrorsToNotifications() private void forwardGeneralLogsToNotifications()
{ {
int recentLogCount = 0; int recentLogCount = 0;
@ -1002,7 +1004,7 @@ namespace osu.Game
Logger.NewEntry += entry => Logger.NewEntry += entry =>
{ {
if (entry.Level < LogLevel.Important || entry.Target == null) return; if (entry.Level < LogLevel.Important || entry.Target > LoggingTarget.Database) return;
const int short_term_display_limit = 3; const int short_term_display_limit = 3;
@ -1035,6 +1037,52 @@ namespace osu.Game
}; };
} }
private void forwardTabletLogsToNotifications()
{
const string tablet_prefix = @"[Tablet] ";
bool notifyOnWarning = true;
Logger.NewEntry += entry =>
{
if (entry.Level < LogLevel.Important || entry.Target != LoggingTarget.Input || !entry.Message.StartsWith(tablet_prefix, StringComparison.OrdinalIgnoreCase))
return;
string message = entry.Message.Replace(tablet_prefix, string.Empty);
if (entry.Level == LogLevel.Error)
{
Schedule(() => Notifications.Post(new SimpleNotification
{
Text = $"Encountered tablet error: \"{message}\"",
Icon = FontAwesome.Solid.PenSquare,
IconColour = Colours.RedDark,
}));
}
else if (notifyOnWarning)
{
Schedule(() => Notifications.Post(new SimpleNotification
{
Text = @"Encountered tablet warning, your tablet may not function correctly. Click here for a list of all tablets supported.",
Icon = FontAwesome.Solid.PenSquare,
IconColour = Colours.YellowDark,
Activated = () =>
{
OpenUrlExternally("https://opentabletdriver.net/Tablets", true);
return true;
}
}));
notifyOnWarning = false;
}
};
Schedule(() =>
{
ITabletHandler tablet = Host.AvailableInputHandlers.OfType<ITabletHandler>().SingleOrDefault();
tablet?.Tablet.BindValueChanged(_ => notifyOnWarning = true, true);
});
}
private Task asyncLoadStream; private Task asyncLoadStream;
/// <summary> /// <summary>

View File

@ -125,6 +125,8 @@ namespace osu.Game
protected SessionStatics SessionStatics { get; private set; } protected SessionStatics SessionStatics { get; private set; }
protected OsuColour Colours { get; private set; }
protected BeatmapManager BeatmapManager { get; private set; } protected BeatmapManager BeatmapManager { get; private set; }
protected BeatmapModelDownloader BeatmapDownloader { get; private set; } protected BeatmapModelDownloader BeatmapDownloader { get; private set; }
@ -311,7 +313,7 @@ namespace osu.Game
dependencies.CacheAs(powerStatus); dependencies.CacheAs(powerStatus);
dependencies.Cache(SessionStatics = new SessionStatics()); dependencies.Cache(SessionStatics = new SessionStatics());
dependencies.Cache(new OsuColour()); dependencies.Cache(Colours = new OsuColour());
RegisterImportHandler(BeatmapManager); RegisterImportHandler(BeatmapManager);
RegisterImportHandler(ScoreManager); RegisterImportHandler(ScoreManager);

View File

@ -3,6 +3,7 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -41,6 +42,12 @@ namespace osu.Game.Overlays.Notifications
} }
} }
public ColourInfo IconColour
{
get => IconContent.Colour;
set => IconContent.Colour = value;
}
private TextFlowContainer? textDrawable; private TextFlowContainer? textDrawable;
private SpriteIcon? iconDrawable; private SpriteIcon? iconDrawable;

View File

@ -44,6 +44,28 @@ namespace osu.Game.Skinning
: base(skin, resources) : base(skin, resources)
{ {
this.resources = resources; this.resources = resources;
Configuration.CustomComboColours = new List<Color4>
{
// Standard combo progression order is green - blue - red - yellow.
// But for whatever reason, this starts from index 1, not 0.
//
// We've added two new combo colours in argon, so to ensure the initial rotation matches,
// this same progression is in slots 1 - 4.
// Orange
new Color4(241, 116, 0, 255),
// Green
new Color4(0, 241, 53, 255),
// Blue
new Color4(0, 82, 241, 255),
// Red
new Color4(241, 0, 0, 255),
// Yellow
new Color4(232, 235, 0, 255),
// Purple
new Color4(92, 0, 241, 255),
};
} }
public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT);

View File

@ -35,7 +35,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Realm" Version="10.15.1" /> <PackageReference Include="Realm" Version="10.15.1" />
<PackageReference Include="ppy.osu.Framework" Version="2022.916.1" /> <PackageReference Include="ppy.osu.Framework" Version="2022.922.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
<PackageReference Include="Sentry" Version="3.20.1" /> <PackageReference Include="Sentry" Version="3.20.1" />
<PackageReference Include="SharpCompress" Version="0.32.2" /> <PackageReference Include="SharpCompress" Version="0.32.2" />

View File

@ -61,7 +61,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.916.1" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2022.922.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
</ItemGroup> </ItemGroup>
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) --> <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
@ -82,7 +82,7 @@
<PackageReference Include="DiffPlex" Version="1.7.1" /> <PackageReference Include="DiffPlex" Version="1.7.1" />
<PackageReference Include="Humanizer" Version="2.14.1" /> <PackageReference Include="Humanizer" Version="2.14.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2022.916.1" /> <PackageReference Include="ppy.osu.Framework" Version="2022.922.0" />
<PackageReference Include="SharpCompress" Version="0.32.1" /> <PackageReference Include="SharpCompress" Version="0.32.1" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />