diff --git a/osu.Android.props b/osu.Android.props
index b691751f13..8711ceec64 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs
index ca9bc89473..2b0098744f 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Acronym => "HO";
- public override double ScoreMultiplier => 1;
+ public override double ScoreMultiplier => 0.9;
public override LocalisableString Description => @"Replaces all hold notes with normal notes.";
diff --git a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs
index 01d83b55e6..b4727b3c02 100644
--- a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests
new object[] { LegacyMods.Autoplay, new[] { typeof(OsuModAutoplay) } },
new object[] { LegacyMods.SpunOut, new[] { typeof(OsuModSpunOut) } },
new object[] { LegacyMods.Autopilot, new[] { typeof(OsuModAutopilot) } },
- new object[] { LegacyMods.Target, new[] { typeof(OsuModTarget) } },
+ new object[] { LegacyMods.Target, new[] { typeof(OsuModTargetPractice) } },
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) } }
};
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs
index 618fcfe05d..1621bb50b1 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override LocalisableString Description => "It never gets boring!";
- public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTarget)).ToArray();
+ public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray();
[SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(SettingsSlider))]
public BindableFloat AngleSharpness { get; } = new BindableFloat(7)
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
index 9708800daa..f691731afe 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override ModType Type => ModType.Automation;
public override LocalisableString Description => @"Spinners will be automatically completed.";
public override double ScoreMultiplier => 0.9;
- public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTarget) };
+ public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
{
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
index 67b19124e1..af37f1e2e5 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => @"Once you start a slider, follow precisely or get a miss.";
public override double ScoreMultiplier => 1.0;
- public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTarget) };
+ public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTargetPractice) };
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
{
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
index 429fe30fc5..b4edb1581e 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[]
{
typeof(OsuModAutopilot),
- typeof(OsuModTarget),
+ typeof(OsuModTargetPractice),
}).ToArray();
}
}
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
similarity index 98%
rename from osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs
rename to osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
index 406968ba08..55c20eebe9 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
@@ -32,16 +32,15 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Mods
{
- public class OsuModTarget : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset,
- IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride,
- IHasSeed, IHidesApproachCircles
+ public class OsuModTargetPractice : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset,
+ IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride, IHasSeed, IHidesApproachCircles
{
- public override string Name => "Target";
+ public override string Name => "Target Practice";
public override string Acronym => "TP";
public override ModType Type => ModType.Conversion;
public override IconUsage? Icon => OsuIcon.ModTarget;
public override LocalisableString Description => @"Practice keeping up with the beat of the song.";
- public override double ScoreMultiplier => 1;
+ public override double ScoreMultiplier => 0.1;
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[]
{
diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs
index 69df12ff6d..79a566e33c 100644
--- a/osu.Game.Rulesets.Osu/OsuRuleset.cs
+++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs
@@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Osu
yield return new OsuModSpunOut();
if (mods.HasFlagFast(LegacyMods.Target))
- yield return new OsuModTarget();
+ yield return new OsuModTargetPractice();
if (mods.HasFlagFast(LegacyMods.TouchDevice))
yield return new OsuModTouchDevice();
@@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu
value |= LegacyMods.SpunOut;
break;
- case OsuModTarget:
+ case OsuModTargetPractice:
value |= LegacyMods.Target;
break;
@@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu
case ModType.Conversion:
return new Mod[]
{
- new OsuModTarget(),
+ new OsuModTargetPractice(),
new OsuModDifficultyAdjust(),
new OsuModClassic(),
new OsuModRandom(),
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs
index 36dc8c801d..4ac71e4225 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs
@@ -121,12 +121,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f));
flash.Colour = colour.NewValue;
- updateStateTransforms(drawableObject, drawableObject.State.Value);
+ // Accent colour may be changed many times during a paused gameplay state.
+ // Schedule the change to avoid transforms piling up.
+ Scheduler.AddOnce(updateStateTransforms);
}, true);
drawableObject.ApplyCustomUpdateState += updateStateTransforms;
}
+ private void updateStateTransforms() => updateStateTransforms(drawableObject, drawableObject.State.Value);
+
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
{
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
@@ -171,7 +175,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
// This is to give it a bomb-like effect, with the border "triggering" its animation when getting close.
using (BeginDelayedSequence(flash_in_duration / 12))
{
- outerGradient.ResizeTo(outerGradient.Size * shrink_size, resize_duration, Easing.OutElasticHalf);
+ outerGradient.ResizeTo(OUTER_GRADIENT_SIZE * shrink_size, resize_duration, Easing.OutElasticHalf);
outerGradient
.FadeColour(Color4.White, 80)
.Then()
diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs
index a98f931e7a..495a221159 100644
--- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs
+++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs
@@ -7,6 +7,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
+using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
@@ -66,7 +67,7 @@ namespace osu.Game.Tests.Editing
{
AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier);
- assertSnapDistance(100 * multiplier);
+ assertSnapDistance(100 * multiplier, null, true);
}
[TestCase(1)]
@@ -79,7 +80,20 @@ namespace osu.Game.Tests.Editing
{
SliderVelocity = multiplier
}
- });
+ }, false);
+ }
+
+ [TestCase(1)]
+ [TestCase(2)]
+ public void TestSpeedMultiplierDoesChangeDistanceSnap(float multiplier)
+ {
+ assertSnapDistance(100 * multiplier, new HitObject
+ {
+ DifficultyControlPoint = new DifficultyControlPoint
+ {
+ SliderVelocity = multiplier
+ }
+ }, true);
}
[TestCase(1)]
@@ -88,7 +102,32 @@ namespace osu.Game.Tests.Editing
{
AddStep($"set divisor = {divisor}", () => BeatDivisor.Value = divisor);
- assertSnapDistance(100f / divisor);
+ assertSnapDistance(100f / divisor, null, true);
+ }
+
+ ///
+ /// The basic distance-duration functions should always include slider velocity of the reference object.
+ ///
+ [Test]
+ public void TestConversionsWithSliderVelocity()
+ {
+ const float base_distance = 100;
+ const float slider_velocity = 1.2f;
+
+ var referenceObject = new HitObject
+ {
+ DifficultyControlPoint = new DifficultyControlPoint
+ {
+ SliderVelocity = slider_velocity
+ }
+ };
+
+ assertSnapDistance(base_distance * slider_velocity, referenceObject, true);
+ assertSnappedDistance(base_distance * slider_velocity + 10, base_distance * slider_velocity, referenceObject);
+ assertSnappedDuration(base_distance * slider_velocity + 10, 1000, referenceObject);
+
+ assertDistanceToDuration(base_distance * slider_velocity, 1000, referenceObject);
+ assertDurationToDistance(1000, base_distance * slider_velocity, referenceObject);
}
[Test]
@@ -197,20 +236,20 @@ namespace osu.Game.Tests.Editing
assertSnappedDistance(400, 400);
}
- private void assertSnapDistance(float expectedDistance, HitObject? hitObject = null)
- => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(hitObject ?? new HitObject()), () => Is.EqualTo(expectedDistance));
+ private void assertSnapDistance(float expectedDistance, HitObject? referenceObject, bool includeSliderVelocity)
+ => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(referenceObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON));
- private void assertDurationToDistance(double duration, float expectedDistance)
- => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(new HitObject(), duration) == expectedDistance);
+ private void assertDurationToDistance(double duration, float expectedDistance, HitObject? referenceObject = null)
+ => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(referenceObject ?? new HitObject(), duration), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON));
- private void assertDistanceToDuration(float distance, double expectedDuration)
- => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(new HitObject(), distance) == expectedDuration);
+ private void assertDistanceToDuration(float distance, double expectedDuration, HitObject? referenceObject = null)
+ => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON));
- private void assertSnappedDuration(float distance, double expectedDuration)
- => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(new HitObject(), distance) == expectedDuration);
+ private void assertSnappedDuration(float distance, double expectedDuration, HitObject? referenceObject = null)
+ => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON));
- private void assertSnappedDistance(float distance, float expectedDistance)
- => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(new HitObject(), distance) == expectedDistance);
+ private void assertSnappedDistance(float distance, float expectedDistance, HitObject? referenceObject = null)
+ => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON));
private class TestHitObjectComposer : OsuHitObjectComposer
{
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs
index 53b6db2277..01a49c7dea 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs
@@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.Editing
IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier;
- public float GetBeatSnapDistanceAt(HitObject referenceObject) => beat_snap_distance;
+ public float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) => beat_snap_distance;
public float DurationToDistance(HitObject referenceObject, double duration) => (float)duration;
diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs
index 4419791e43..c7c244bf0e 100644
--- a/osu.Game/Beatmaps/BeatmapConverter.cs
+++ b/osu.Game/Beatmaps/BeatmapConverter.cs
@@ -47,6 +47,7 @@ namespace osu.Game.Beatmaps
// Shallow clone isn't enough to ensure we don't mutate beatmap info unexpectedly.
// Can potentially be removed after `Beatmap.Difficulty` doesn't save back to `Beatmap.BeatmapInfo`.
original.BeatmapInfo = original.BeatmapInfo.Clone();
+ original.ControlPointInfo = original.ControlPointInfo.DeepClone();
return ConvertBeatmap(original, cancellationToken);
}
diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs
index 0833c7eb8b..08a569269e 100644
--- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs
@@ -25,10 +25,9 @@ namespace osu.Game.Graphics.UserInterfaceV2
protected override DirectorySelectorDirectory CreateDirectoryItem(DirectoryInfo directory, string displayName = null) => new OsuBreadcrumbDisplayDirectory(directory, displayName);
- [BackgroundDependencyLoader]
- private void load()
+ public OsuDirectorySelectorBreadcrumbDisplay()
{
- Height = 50;
+ Padding = new MarginPadding(15);
}
private class OsuBreadcrumbDisplayComputer : OsuBreadcrumbDisplayDirectory
diff --git a/osu.Game/Online/PersistentEndpointClient.cs b/osu.Game/Online/PersistentEndpointClient.cs
index e0307f7c6a..32c243fbbb 100644
--- a/osu.Game/Online/PersistentEndpointClient.cs
+++ b/osu.Game/Online/PersistentEndpointClient.cs
@@ -9,10 +9,21 @@ namespace osu.Game.Online
{
public abstract class PersistentEndpointClient : IAsyncDisposable
{
+ ///
+ /// An event notifying the that the connection has been closed
+ ///
public event Func? Closed;
+ ///
+ /// Notifies the that the connection has been closed.
+ ///
+ /// The exception that the connection closed with.
protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask;
+ ///
+ /// Connects the client to the remote service to begin processing messages.
+ ///
+ /// A cancellation token to stop processing messages.
public abstract Task ConnectAsync(CancellationToken cancellationToken);
public virtual ValueTask DisposeAsync()
diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs
index 202f7abe4a..11e8e870d6 100644
--- a/osu.Game/Online/PersistentEndpointClientConnector.cs
+++ b/osu.Game/Online/PersistentEndpointClientConnector.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Online
public abstract class PersistentEndpointClientConnector : IDisposable
{
///
- /// Whether this is connected to the hub, use to access the connection, if this is true.
+ /// Whether the managed connection is currently connected. When true use to access the connection.
///
public IBindable IsConnected => isConnected;
@@ -31,7 +31,7 @@ namespace osu.Game.Online
private CancellationTokenSource connectCancelSource = new CancellationTokenSource();
///
- /// Constructs a new .
+ /// Constructs a new .
///
/// An API provider used to react to connection state changes.
protected PersistentEndpointClientConnector(IAPIProvider api)
@@ -126,6 +126,10 @@ namespace osu.Game.Online
await Task.Delay(5000, cancellationToken).ConfigureAwait(false);
}
+ ///
+ /// Creates a new .
+ ///
+ /// A cancellation token to stop the process.
protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken);
private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken)
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 7384c2a297..f36d83d5c2 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -315,7 +315,7 @@ namespace osu.Game
Beatmap.BindValueChanged(beatmapChanged, true);
applySafeAreaConsiderations = LocalConfig.GetBindable(OsuSetting.SafeAreaConsiderations);
- applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All);
+ applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All, true);
}
private ExternalLinkOpener externalLinkOpener;
diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
index ca7ca79813..b0a2694a0a 100644
--- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
@@ -259,9 +259,9 @@ namespace osu.Game.Rulesets.Edit
return true;
}
- public virtual float GetBeatSnapDistanceAt(HitObject referenceObject)
+ public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true)
{
- return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor);
+ return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor);
}
public virtual float DurationToDistance(HitObject referenceObject, double duration)
diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs
index 5ad1cc78ff..6fbd994e23 100644
--- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs
+++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs
@@ -27,8 +27,9 @@ namespace osu.Game.Rulesets.Edit
/// Retrieves the distance between two points within a timing point that are one beat length apart.
///
/// An object to be used as a reference point for this operation.
+ /// Whether the 's slider velocity should be factored into the returned distance.
/// The distance between two points residing in the timing point that are one beat length apart.
- float GetBeatSnapDistanceAt(HitObject referenceObject);
+ float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true);
///
/// Converts a duration to a distance without applying any snapping.
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index d624164013..e5150576f2 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -266,6 +266,10 @@ namespace osu.Game.Rulesets.Objects.Drawables
updateState(ArmedState.Miss, true);
else
updateState(ArmedState.Idle, true);
+
+ // Combo colour may have been applied via a bindable flow while no object entry was attached.
+ // Update here to ensure we're in a good state.
+ UpdateComboColour();
}
}
diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs
index fdbcd0ed1e..e2b8cd2c4e 100644
--- a/osu.Game/Rulesets/RulesetStore.cs
+++ b/osu.Game/Rulesets/RulesetStore.cs
@@ -158,7 +158,7 @@ namespace osu.Game.Rulesets
}
catch (Exception e)
{
- LogFailedLoad(assembly.FullName, e);
+ LogFailedLoad(assembly.GetName().Name.Split('.').Last(), e);
}
}
@@ -168,14 +168,14 @@ namespace osu.Game.Rulesets
GC.SuppressFinalize(this);
}
- protected virtual void Dispose(bool disposing)
+ protected void Dispose(bool disposing)
{
AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly;
}
protected void LogFailedLoad(string name, Exception exception)
{
- Logger.Log($"Could not load ruleset {name}. Please check for an update from the developer.", level: LogLevel.Error);
+ Logger.Log($"Could not load ruleset \"{name}\". Please check for an update from the developer.", level: LogLevel.Error);
Logger.Log($"Ruleset load failed: {exception}");
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
index 69c7fc2775..c179e7f0c2 100644
--- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
@@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void updateSpacing()
{
float distanceSpacingMultiplier = (float)DistanceSpacingMultiplier.Value;
- float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject);
+ float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject, false);
DistanceBetweenTicks = beatSnapDistance * distanceSpacingMultiplier;
diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs
index dc09676254..cea03d2155 100644
--- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs
@@ -1,22 +1,27 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
+using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays.Settings;
namespace osu.Game.Screens.Play.PlayerSettings
{
- public class PlayerCheckbox : OsuCheckbox
+ public class PlayerCheckbox : SettingsCheckbox
{
- [BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ protected override Drawable CreateControl() => new PlayerCheckboxControl();
+
+ public class PlayerCheckboxControl : OsuCheckbox
{
- Nub.AccentColour = colours.Yellow;
- Nub.GlowingAccentColour = colours.YellowLighter;
- Nub.GlowColour = colours.YellowDark;
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ Nub.AccentColour = colours.Yellow;
+ Nub.GlowingAccentColour = colours.YellowLighter;
+ Nub.GlowColour = colours.YellowDark;
+ }
}
}
}
diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
index e55af0bba7..bb3360acec 100644
--- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
@@ -1,12 +1,9 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Configuration;
-using osu.Game.Graphics.Sprites;
using osu.Game.Localisation;
namespace osu.Game.Screens.Play.PlayerSettings
@@ -24,26 +21,16 @@ namespace osu.Game.Screens.Play.PlayerSettings
{
Children = new Drawable[]
{
- new OsuSpriteText
- {
- Text = GameplaySettingsStrings.BackgroundDim
- },
dimSliderBar = new PlayerSliderBar
{
+ LabelText = GameplaySettingsStrings.BackgroundDim,
DisplayAsPercentage = true
},
- new OsuSpriteText
- {
- Text = GameplaySettingsStrings.BackgroundBlur
- },
blurSliderBar = new PlayerSliderBar
{
+ LabelText = GameplaySettingsStrings.BackgroundBlur,
DisplayAsPercentage = true
},
- new OsuSpriteText
- {
- Text = "Toggles:"
- },
showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo },
beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins },
beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours },
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 9dd0d18817..8d45ebec57 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -35,7 +35,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 6dce938ebf..76d2e727c8 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -62,7 +62,7 @@
-
+
@@ -82,7 +82,7 @@
-
+