diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
index 755e0e7563..78b8957de6 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
@@ -37,19 +37,22 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{
IsForCurrentRuleset = isForCurrentRuleset;
+ var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize);
+ var roundedOverallDifficulty = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty);
+
if (isForCurrentRuleset)
- TargetColumns = (int)Math.Max(1, Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize));
+ TargetColumns = (int)Math.Max(1, roundedCircleSize);
else
{
float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count;
if (percentSliderOrSpinner < 0.2)
TargetColumns = 7;
- else if (percentSliderOrSpinner < 0.3 || Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize) >= 5)
- TargetColumns = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty) > 5 ? 7 : 6;
+ else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5)
+ TargetColumns = roundedOverallDifficulty > 5 ? 7 : 6;
else if (percentSliderOrSpinner > 0.6)
- TargetColumns = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty) > 4 ? 5 : 4;
+ TargetColumns = roundedOverallDifficulty > 4 ? 5 : 4;
else
- TargetColumns = Math.Max(4, Math.Min((int)Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty) + 1, 7));
+ TargetColumns = Math.Max(4, Math.Min((int)roundedOverallDifficulty + 1, 7));
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 5a8bcae277..f32a027f2e 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -158,14 +158,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void UpdateCurrentState(ArmedState state)
{
Ball.FadeIn();
+ Ball.ScaleTo(HitObject.Scale);
using (BeginDelayedSequence(slider.Duration, true))
{
- Body.FadeOut(160);
- Ball.FadeOut(160);
+ const float fade_out_time = 450;
- this.FadeOut(800)
- .Expire();
+ // intentionally pile on an extra FadeOut to make it happen much faster.
+ Ball.FadeOut(fade_out_time / 4, Easing.Out);
+
+ switch (state)
+ {
+ case ArmedState.Hit:
+ Ball.ScaleTo(HitObject.Scale * 1.4f, fade_out_time, Easing.Out);
+ break;
+ }
+
+ this.FadeOut(fade_out_time, Easing.OutQuint).Expire();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
index 2068ad9205..46b4353f9a 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
}
private readonly Slider slider;
- private readonly Box follow;
+ public readonly Box FollowCircle;
private readonly Box ball;
public SliderBall(Slider slider)
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Children = new Drawable[]
{
- follow = new Box
+ FollowCircle = new Box
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
@@ -101,11 +101,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
// If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position.
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos);
- public override void ClearTransforms(bool propagateChildren = false, string targetMember = null)
+ public override void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null)
{
// Consider the case of rewinding - children's transforms are handled internally, so propagating down
// any further will cause weirdness with the Tracking bool below. Let's not propagate further at this point.
- base.ClearTransforms(false, targetMember);
+ base.ClearTransformsAfter(time, false, targetMember);
}
private bool tracking;
@@ -118,8 +118,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
return;
tracking = value;
- follow.ScaleTo(tracking ? 2.8f : 1, 300, Easing.OutQuint);
- follow.FadeTo(tracking ? 0.2f : 0, 300, Easing.OutQuint);
+ FollowCircle.ScaleTo(tracking ? 2.8f : 1, 300, Easing.OutQuint);
+ FollowCircle.FadeTo(tracking ? 0.2f : 0, 300, Easing.OutQuint);
}
}
@@ -129,11 +129,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
base.Update();
- // Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position.
- Tracking = canCurrentlyTrack
- && lastState != null
- && base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position)
- && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
+ if (Time.Current < slider.EndTime)
+ {
+ // Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position.
+ Tracking = canCurrentlyTrack
+ && lastState != null
+ && base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position)
+ && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
+ }
}
public void UpdateProgress(double progress, int repeat)
@@ -141,4 +144,4 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Position = slider.Curve.PositionAt(progress);
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
index 839932c640..a0904ee446 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual(new Vector2(320, 240), sprite.InitialPosition);
Assert.IsTrue(sprite.IsDrawable);
Assert.AreEqual(Anchor.Centre, sprite.Origin);
- Assert.AreEqual("SB/lyric/ja-21.png", sprite.Path);
+ Assert.AreEqual(Path.Combine("SB", "lyric", "ja-21.png"), sprite.Path);
var animation = background.Elements.ElementAt(12) as StoryboardAnimation;
Assert.NotNull(animation);
@@ -82,7 +82,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.IsTrue(animation.IsDrawable);
Assert.AreEqual(AnimationLoopType.LoopForever, animation.LoopType);
Assert.AreEqual(Anchor.Centre, animation.Origin);
- Assert.AreEqual("SB/red jitter/red_0000.jpg", animation.Path);
+ Assert.AreEqual(Path.Combine("SB", "red jitter", "red_0000.jpg"), animation.Path);
Assert.AreEqual(78993, animation.StartTime);
}
}
diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
index f031ebe353..59123380af 100644
--- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
+++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
@@ -64,24 +64,24 @@ namespace osu.Game.Beatmaps.ControlPoints
/// The timing control point.
public TimingControlPoint TimingPointAt(double time) => binarySearch(TimingPoints, time, TimingPoints.FirstOrDefault());
- [JsonIgnore]
///
/// Finds the maximum BPM represented by any timing control point.
///
+ [JsonIgnore]
public double BPMMaximum =>
60000 / (TimingPoints.OrderBy(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
- [JsonIgnore]
///
/// Finds the minimum BPM represented by any timing control point.
///
+ [JsonIgnore]
public double BPMMinimum =>
60000 / (TimingPoints.OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
- [JsonIgnore]
///
/// Finds the mode BPM (most common BPM) represented by the control points.
///
+ [JsonIgnore]
public double BPMMode =>
60000 / (TimingPoints.GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
index 8da6a0cefb..168f37e44e 100644
--- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
@@ -266,6 +266,6 @@ namespace osu.Game.Beatmaps.Formats
throw new InvalidDataException($@"Unknown origin: {value}");
}
- private string cleanFilename(string path) => FileSafety.PathStandardise(path.Trim('\"'));
+ private string cleanFilename(string path) => FileSafety.PathSanitise(path.Trim('\"'));
}
}
diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs
index ea74c67f6c..35e3f10526 100644
--- a/osu.Game/Graphics/UserInterface/LineGraph.cs
+++ b/osu.Game/Graphics/UserInterface/LineGraph.cs
@@ -73,8 +73,6 @@ namespace osu.Game.Graphics.UserInterface
});
}
- private bool pending;
-
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
{
if ((invalidation & Invalidation.DrawSize) > 0)
diff --git a/osu.Game/IO/Serialization/Converters/TypedListConverter.cs b/osu.Game/IO/Serialization/Converters/TypedListConverter.cs
index b218f76b53..d63cceccf3 100644
--- a/osu.Game/IO/Serialization/Converters/TypedListConverter.cs
+++ b/osu.Game/IO/Serialization/Converters/TypedListConverter.cs
@@ -9,11 +9,11 @@ using Newtonsoft.Json.Linq;
namespace osu.Game.IO.Serialization.Converters
{
///
- /// A type of that serializes a alongside
+ /// A type of that serializes a alongside
/// a lookup table for the types contained. The lookup table is used in deserialization to
/// reconstruct the objects with their original types.
///
- /// The type of objects contained in the this attribute is attached to.
+ /// The type of objects contained in the this attribute is attached to.
public class TypedListConverter : JsonConverter
{
private readonly bool requiresTypeVersion;
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
index 06e4684d4c..e40ce14326 100644
--- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
+++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
@@ -4,7 +4,6 @@
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
@@ -16,7 +15,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
public abstract class DrawableProfileScore : DrawableProfileRow
{
- private readonly FillFlowContainer metadata;
private readonly ScoreModsContainer modsContainer;
protected readonly Score Score;
diff --git a/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObject.cs b/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObject.cs
index 66dbc85095..fb9d7128c0 100644
--- a/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObject.cs
+++ b/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObject.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
///
/// Applies this to a list of s.
///
- /// The list of s to apply to.
+ /// The list of s to apply to.
void ApplyToDrawableHitObjects(IEnumerable drawables);
}
}
diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs
index c96194f63d..1f332312ba 100644
--- a/osu.Game/Screens/Loader.cs
+++ b/osu.Game/Screens/Loader.cs
@@ -101,8 +101,6 @@ namespace osu.Game.Screens
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
}
- private Shader currentLoadTarget;
-
protected override void Update()
{
base.Update();
diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
index 729cb458c2..c25ba66475 100644
--- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs
+++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
@@ -20,6 +20,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Cursor;
+using osu.Framework.Localisation;
namespace osu.Game.Screens.Select
{
@@ -86,6 +87,8 @@ namespace osu.Game.Screens.Select
public OsuSpriteText ArtistLabel { get; private set; }
public FillFlowContainer MapperContainer { get; private set; }
public FillFlowContainer InfoLabelContainer { get; private set; }
+ private UnicodeBindableString titleBinding;
+ private UnicodeBindableString artistBinding;
public BufferedWedgeInfo(WorkingBeatmap working)
{
@@ -93,7 +96,7 @@ namespace osu.Game.Screens.Select
}
[BackgroundDependencyLoader]
- private void load()
+ private void load(LocalisationEngine localisation)
{
var beatmapInfo = working.BeatmapInfo;
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
@@ -102,6 +105,9 @@ namespace osu.Game.Screens.Select
CacheDrawnFrameBuffer = true;
RelativeSizeAxes = Axes.Both;
+ titleBinding = localisation.GetUnicodePreference(metadata.TitleUnicode, metadata.Title);
+ artistBinding = localisation.GetUnicodePreference(metadata.ArtistUnicode, metadata.Artist);
+
Children = new Drawable[]
{
// We will create the white-to-black gradient by modulating transparency and having
@@ -167,13 +173,11 @@ namespace osu.Game.Screens.Select
TitleLabel = new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
- Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title,
TextSize = 28,
},
ArtistLabel = new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
- Text = metadata.Artist,
TextSize = 17,
},
MapperContainer = new FillFlowContainer
@@ -193,6 +197,15 @@ namespace osu.Game.Screens.Select
}
}
};
+ artistBinding.ValueChanged += value => setMetadata(metadata.Source);
+ artistBinding.TriggerChange();
+ }
+
+ private void setMetadata(string source)
+ {
+ ArtistLabel.Text = artistBinding.Value;
+ TitleLabel.Text = string.IsNullOrEmpty(source) ? titleBinding.Value : source + " — " + titleBinding.Value;
+ ForceRedraw();
}
private InfoLabel[] getInfoLabels()
diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
index a54eeb562e..a600693e31 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
@@ -10,8 +10,6 @@ namespace osu.Game.Screens.Select.Carousel
///
public class CarouselGroup : CarouselItem
{
- private readonly List items;
-
protected override DrawableCarouselItem CreateDrawableRepresentation() => null;
public IReadOnlyList Children => InternalChildren;
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
index 4b999f9b87..40ffcfdc80 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
@@ -31,8 +31,6 @@ namespace osu.Game.Screens.Select.Carousel
private readonly BeatmapSetInfo beatmapSet;
- private readonly FillFlowContainer difficultyIcons;
-
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
: base(set)
{
diff --git a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs
index 7563c08c8b..69a478f12a 100644
--- a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs
+++ b/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Screens.Select.Leaderboards
{
private readonly SpriteIcon icon;
- public Action Action;
+ public new Action Action;
public RetryButton()
{