diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 4a6bd45007..020a64a26b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -48,10 +48,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables InternalChildren = new Drawable[] { - Body = new SnakingSliderBody(s) - { - PathRadius = s.Scale * OsuHitObject.OBJECT_RADIUS, - }, + Body = new SnakingSliderBody(s), ticks = new Container { RelativeSizeAxes = Axes.Both }, repeatPoints = new Container { RelativeSizeAxes = Axes.Both }, Ball = new SliderBall(s, this) @@ -105,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); scaleBindable.BindValueChanged(scale => { - Body.PathRadius = scale.NewValue * 64; + updatePathRadius(); Ball.Scale = new Vector2(scale.NewValue); }); @@ -157,16 +154,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Body.RecyclePath(); } + private float sliderPathRadius; + protected override void SkinChanged(ISkinSource skin, bool allowFallback) { base.SkinChanged(skin, allowFallback); Body.BorderSize = skin.GetValue(s => s.SliderBorderSize) ?? SliderBody.DEFAULT_BORDER_SIZE; + sliderPathRadius = skin.GetValue(s => s.SliderPathRadius) ?? OsuHitObject.OBJECT_RADIUS; + updatePathRadius(); + Body.AccentColour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : (Color4?)null) ?? AccentColour.Value; Body.BorderColour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : (Color4?)null) ?? Color4.White; Ball.AccentColour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? AccentColour.Value; } + private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius; + protected override void CheckForResult(bool userTriggered, double timeOffset) { if (userTriggered || Time.Current < slider.EndTime) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index b3492a2b31..ea81527fa9 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -101,11 +101,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }, }, } - }) + }, confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, } }; diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index e28ff5f460..8b6b483618 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.UI Anchor = Anchor.Centre; Origin = Anchor.Centre; - Size = new Vector2(0.75f); + Size = new Vector2(0.8f); InternalChild = new Container { diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 513a024a36..af9a24df42 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -24,6 +24,13 @@ namespace osu.Game.Skinning protected IResourceStore Samples; + /// + /// On osu-stable, hitcircles have 5 pixels of transparent padding on each side to allow for shadows etc. + /// Their hittable area is 128px, but the actual circle portion is 118px. + /// We must account for some gameplay elements such as slider bodies, where this padding is not present. + /// + private const float legacy_circle_radius = 64 - 5; + public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini") { @@ -41,6 +48,16 @@ namespace osu.Game.Skinning Samples = audioManager.GetSampleStore(storage); Textures = new TextureStore(new TextureLoaderStore(storage)); + + bool hasHitCircle = false; + + using (var testStream = storage.GetStream("hitcircle")) + hasHitCircle |= testStream != null; + + if (hasHitCircle) + { + Configuration.SliderPathRadius = legacy_circle_radius; + } } protected override void Dispose(bool isDisposing) @@ -95,7 +112,6 @@ namespace osu.Game.Skinning public override Texture GetTexture(string componentName) { float ratio = 2; - var texture = Textures.Get($"{componentName}@2x"); if (texture == null) @@ -105,7 +121,19 @@ namespace osu.Game.Skinning } if (texture != null) - texture.ScaleAdjust = ratio / 0.72f; // brings sizing roughly in-line with stable + { + texture.ScaleAdjust = ratio; + + switch (componentName) + { + case "cursormiddle": + case "cursortrail": + case "cursor": + // apply inverse of adjustment in OsuPlayfieldAdjustmentContainer for non-gameplay-scale textures. + texture.ScaleAdjust *= 1.6f; + break; + } + } return texture; } diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 043622f8ce..93b599f9f6 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -27,6 +27,8 @@ namespace osu.Game.Skinning public float? SliderBorderSize { get; set; } + public float? SliderPathRadius { get; set; } + public bool? CursorExpand { get; set; } = true; } }