diff --git a/osu.Android.props b/osu.Android.props
index 9e729d8705..cb848c0433 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaColumnTypeTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaColumnTypeTest.cs
new file mode 100644
index 0000000000..40a6e1fdae
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaColumnTypeTest.cs
@@ -0,0 +1,50 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Game.Rulesets.Mania.Beatmaps;
+using NUnit.Framework;
+
+namespace osu.Game.Rulesets.Mania.Tests
+{
+ [TestFixture]
+ public class ManiaColumnTypeTest
+ {
+ [TestCase(new[]
+ {
+ ColumnType.Special
+ }, 1)]
+ [TestCase(new[]
+ {
+ ColumnType.Odd,
+ ColumnType.Even,
+ ColumnType.Even,
+ ColumnType.Odd
+ }, 4)]
+ [TestCase(new[]
+ {
+ ColumnType.Odd,
+ ColumnType.Even,
+ ColumnType.Odd,
+ ColumnType.Special,
+ ColumnType.Odd,
+ ColumnType.Even,
+ ColumnType.Odd
+ }, 7)]
+ public void Test(IEnumerable expected, int columns)
+ {
+ var definition = new StageDefinition
+ {
+ Columns = columns
+ };
+ var results = getResults(definition);
+ Assert.AreEqual(expected, results);
+ }
+
+ private IEnumerable getResults(StageDefinition definition)
+ {
+ for (var i = 0; i < definition.Columns; i++)
+ yield return definition.GetTypeOfColumn(i);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs
index c807e98871..ff4865c71d 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs
@@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
using osuTK.Graphics;
@@ -26,7 +27,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
this.column = new Column(column)
{
Action = { Value = action },
- AccentColour = Color4.Orange
+ AccentColour = Color4.Orange,
+ ColumnType = column % 2 == 0 ? ColumnType.Even : ColumnType.Odd
};
InternalChild = content = new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4)
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs
new file mode 100644
index 0000000000..0d5ebd33e9
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs
@@ -0,0 +1,27 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Game.Rulesets.Mania.Beatmaps;
+using osu.Game.Rulesets.Mania.UI;
+
+namespace osu.Game.Rulesets.Mania.Tests.Skinning
+{
+ public class TestSceneStage : ManiaSkinnableTestScene
+ {
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ SetContents(() =>
+ {
+ ManiaAction normalAction = ManiaAction.Key1;
+ ManiaAction specialAction = ManiaAction.Special1;
+
+ return new ManiaInputManager(new ManiaRuleset().RulesetInfo, 4)
+ {
+ Child = new ManiaStage(0, new StageDefinition { Columns = 4 }, ref normalAction, ref specialAction)
+ };
+ });
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ColumnType.cs b/osu.Game.Rulesets.Mania/Beatmaps/ColumnType.cs
new file mode 100644
index 0000000000..8f904530bc
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ColumnType.cs
@@ -0,0 +1,12 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+namespace osu.Game.Rulesets.Mania.Beatmaps
+{
+ public enum ColumnType
+ {
+ Even,
+ Odd,
+ Special
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
index dff7cb72ce..2557f2acdf 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Beatmaps
@@ -21,5 +22,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// The 0-based column index.
/// Whether the column is a special column.
public bool IsSpecialColumn(int column) => Columns % 2 == 1 && column == Columns / 2;
+
+ ///
+ /// Get the type of column given a column index.
+ ///
+ /// The 0-based column index.
+ /// The type of the column.
+ public ColumnType GetTypeOfColumn(int column)
+ {
+ if (IsSpecialColumn(column))
+ return ColumnType.Special;
+
+ int distanceToEdge = Math.Min(column, (Columns - 1) - column);
+ return distanceToEdge % 2 == 0 ? ColumnType.Odd : ColumnType.Even;
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs
index e7fb331079..643d92ff41 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyBodyPiece.cs
@@ -35,8 +35,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject)
{
- string imageName = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage, column.Index))?.Value
+ string imageName = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value
?? $"mania-note{FallbackColumnIndex}L";
sprite = skin.GetAnimation(imageName, true, true).With(d =>
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs
index 96b28964d3..7e8f720e99 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
-using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning;
using osuTK;
@@ -16,19 +15,13 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Skinning
{
- public class LegacyColumnBackground : CompositeDrawable, IKeyBindingHandler
+ public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler
{
private readonly IBindable direction = new Bindable();
private Container lightContainer;
private Sprite light;
- [Resolved]
- private Column column { get; set; }
-
- [Resolved(CanBeNull = true)]
- private ManiaStage stage { get; set; }
-
public LegacyColumnBackground()
{
RelativeSizeAxes = Axes.Both;
@@ -37,20 +30,21 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
{
- string lightImage = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightImage, 0))?.Value
+ string lightImage = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.LightImage, 0)?.Value
?? "mania-stage-light";
- float leftLineWidth = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LeftLineWidth, column.Index))
- ?.Value ?? 1;
- float rightLineWidth = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.RightLineWidth, column.Index))
- ?.Value ?? 1;
+ float leftLineWidth = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.LeftLineWidth)
+ ?.Value ?? 1;
+ float rightLineWidth = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.RightLineWidth)
+ ?.Value ?? 1;
bool hasLeftLine = leftLineWidth > 0;
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m
- || stage == null || column.Index == stage.Columns.Count - 1;
+ || Stage == null || Column.Index == Stage.Columns.Count - 1;
+
+ float lightPosition = skin.GetConfig(
+ new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightPosition))?.Value
+ ?? 0;
InternalChildren = new Drawable[]
{
@@ -77,6 +71,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
{
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Bottom = lightPosition },
Child = light = new Sprite
{
Anchor = Anchor.BottomCentre,
@@ -109,7 +104,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
public bool OnPressed(ManiaAction action)
{
- if (action == column.Action.Value)
+ if (action == Column.Action.Value)
{
light.FadeIn();
light.ScaleTo(Vector2.One);
@@ -123,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
// Todo: Should be 400 * 100 / CurrentBPM
const double animation_length = 250;
- if (action == column.Action.Value)
+ if (action == Column.Action.Value)
{
light.FadeTo(0, animation_length);
light.ScaleTo(new Vector2(1, 0), animation_length);
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs
index 3e550808f3..53e4f3cd14 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyHitTarget.cs
@@ -7,20 +7,16 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Mania.Skinning
{
- public class LegacyHitTarget : CompositeDrawable
+ public class LegacyHitTarget : LegacyManiaElement
{
private readonly IBindable direction = new Bindable();
- [Resolved(CanBeNull = true)]
- private ManiaStage stage { get; set; }
-
private Container directionContainer;
public LegacyHitTarget()
@@ -31,12 +27,10 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
{
- string targetImage = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HitTargetImage))?.Value
+ string targetImage = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.HitTargetImage)?.Value
?? "mania-stage-hint";
- bool showJudgementLine = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.ShowJudgementLine))?.Value
+ bool showJudgementLine = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.ShowJudgementLine)?.Value
?? true;
InternalChild = directionContainer = new Container
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs
index 6afc86c4fa..d2541772cc 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyKeyArea.cs
@@ -36,12 +36,10 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
{
- string upImage = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.KeyImage, column.Index))?.Value
+ string upImage = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.KeyImage)?.Value
?? $"mania-key{FallbackColumnIndex}";
- string downImage = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.KeyImageDown, column.Index))?.Value
+ string downImage = GetManiaSkinConfig(skin, LegacyManiaSkinConfigurationLookups.KeyImageDown)?.Value
?? $"mania-key{FallbackColumnIndex}D";
InternalChild = directionContainer = new Container
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs
index 231a55a7e2..05b731ec5d 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs
@@ -1,41 +1,48 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
+using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.Skinning
{
///
/// A which is placed somewhere within a .
///
- public class LegacyManiaColumnElement : CompositeDrawable
+ public class LegacyManiaColumnElement : LegacyManiaElement
{
- [Resolved(CanBeNull = true)]
- [CanBeNull]
- protected ManiaStage Stage { get; private set; }
-
[Resolved]
protected Column Column { get; private set; }
///
- /// The column index to use for texture lookups, in the case of no user-provided configuration.
+ /// The column type identifier to use for texture lookups, in the case of no user-provided configuration.
///
- protected int FallbackColumnIndex { get; private set; }
+ protected string FallbackColumnIndex { get; private set; }
[BackgroundDependencyLoader]
private void load()
{
- if (Stage == null)
- FallbackColumnIndex = Column.Index % 2 + 1;
- else
+ switch (Column.ColumnType)
{
- int dist = Math.Min(Column.Index, Stage.Columns.Count - Column.Index - 1);
- FallbackColumnIndex = dist % 2 + 1;
+ case ColumnType.Special:
+ FallbackColumnIndex = "S";
+ break;
+
+ case ColumnType.Odd:
+ FallbackColumnIndex = "1";
+ break;
+
+ case ColumnType.Even:
+ FallbackColumnIndex = "2";
+ break;
}
}
+
+ protected override IBindable GetManiaSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? index = null)
+ => base.GetManiaSkinConfig(skin, lookup, index ?? Column.Index);
}
}
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyManiaElement.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaElement.cs
new file mode 100644
index 0000000000..2fb229862f
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaElement.cs
@@ -0,0 +1,32 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using JetBrains.Annotations;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Skinning;
+
+namespace osu.Game.Rulesets.Mania.Skinning
+{
+ ///
+ /// A mania legacy skin element.
+ ///
+ public class LegacyManiaElement : CompositeDrawable
+ {
+ [Resolved(CanBeNull = true)]
+ [CanBeNull]
+ protected ManiaStage Stage { get; private set; }
+
+ ///
+ /// Retrieve a per-column-count skin configuration.
+ ///
+ /// The skin from which configuration is retrieved.
+ /// The value to retrieve.
+ /// If not null, denotes the index of the column to which the entry applies.
+ protected virtual IBindable GetManiaSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? index = null)
+ => skin.GetConfig(
+ new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, lookup, index));
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyNotePiece.cs
index e74509febd..d2ceb06d0b 100644
--- a/osu.Game.Rulesets.Mania/Skinning/LegacyNotePiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/LegacyNotePiece.cs
@@ -83,8 +83,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
break;
}
- string noteImage = skin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, lookup, Column.Index))?.Value
+ string noteImage = GetManiaSkinConfig(skin, lookup)?.Value
?? $"mania-note{FallbackColumnIndex}{suffix}";
return skin.GetTexture(noteImage);
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index 9e0e2c157e..153345dde7 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -16,6 +16,7 @@ using osu.Game.Rulesets.Mania.UI.Components;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning;
using osuTK;
+using osu.Game.Rulesets.Mania.Beatmaps;
namespace osu.Game.Rulesets.Mania.UI
{
@@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.UI
public class Column : ScrollingPlayfield, IKeyBindingHandler, IHasAccentColour
{
public const float COLUMN_WIDTH = 80;
- private const float special_column_width = 70;
+ public const float SPECIAL_COLUMN_WIDTH = 70;
///
/// The index of this column as part of the whole playfield.
@@ -41,7 +42,6 @@ namespace osu.Game.Rulesets.Mania.UI
Index = index;
RelativeSizeAxes = Axes.Y;
- Width = COLUMN_WIDTH;
Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
{
@@ -66,21 +66,9 @@ namespace osu.Game.Rulesets.Mania.UI
public override Axes RelativeSizeAxes => Axes.Y;
- private bool isSpecial;
+ public ColumnType ColumnType { get; set; }
- public bool IsSpecial
- {
- get => isSpecial;
- set
- {
- if (isSpecial == value)
- return;
-
- isSpecial = value;
-
- Width = isSpecial ? special_column_width : COLUMN_WIDTH;
- }
- }
+ public bool IsSpecial => ColumnType == ColumnType.Special;
public Color4 AccentColour { get; set; }
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index fb6e8a87e5..c3c69b0ff3 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osu.Framework.Allocation;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
@@ -12,66 +10,42 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.UI.Components
{
- public class ColumnHitObjectArea : SkinReloadableDrawable
+ public class ColumnHitObjectArea : HitObjectArea
{
public readonly Container Explosions;
-
- [Resolved(CanBeNull = true)]
- private ManiaStage stage { get; set; }
-
- private readonly IBindable direction = new Bindable();
private readonly Drawable hitTarget;
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
+ : base(hitObjectContainer)
{
- InternalChildren = new[]
+ AddRangeInternal(new[]
{
hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget())
{
RelativeSizeAxes = Axes.X,
+ Depth = 1
},
- hitObjectContainer,
- Explosions = new Container { RelativeSizeAxes = Axes.Both }
- };
+ Explosions = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Depth = -1,
+ }
+ });
}
- [BackgroundDependencyLoader]
- private void load(IScrollingInfo scrollingInfo)
+ protected override void UpdateHitPosition()
{
- direction.BindTo(scrollingInfo.Direction);
- direction.BindValueChanged(onDirectionChanged, true);
- }
+ base.UpdateHitPosition();
- protected override void SkinChanged(ISkinSource skin, bool allowFallback)
- {
- base.SkinChanged(skin, allowFallback);
- updateHitPosition();
- }
-
- private void onDirectionChanged(ValueChangedEvent direction)
- {
- updateHitPosition();
- }
-
- private void updateHitPosition()
- {
- float hitPosition = CurrentSkin.GetConfig(
- new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HitPosition))?.Value
- ?? ManiaStage.HIT_TARGET_POSITION;
-
- if (direction.Value == ScrollingDirection.Up)
+ if (Direction.Value == ScrollingDirection.Up)
{
hitTarget.Anchor = hitTarget.Origin = Anchor.TopLeft;
-
- Padding = new MarginPadding { Top = hitPosition };
- Explosions.Padding = new MarginPadding { Top = DefaultNotePiece.NOTE_HEIGHT };
+ Explosions.Padding = new MarginPadding { Top = DefaultNotePiece.NOTE_HEIGHT / 2 };
}
else
{
hitTarget.Anchor = hitTarget.Origin = Anchor.BottomLeft;
-
- Padding = new MarginPadding { Bottom = hitPosition };
- Explosions.Padding = new MarginPadding { Bottom = DefaultNotePiece.NOTE_HEIGHT };
+ Explosions.Padding = new MarginPadding { Bottom = DefaultNotePiece.NOTE_HEIGHT / 2 };
}
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs
new file mode 100644
index 0000000000..9e62445c81
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs
@@ -0,0 +1,57 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.UI;
+using osu.Game.Rulesets.UI.Scrolling;
+using osu.Game.Skinning;
+
+namespace osu.Game.Rulesets.Mania.UI.Components
+{
+ public class HitObjectArea : SkinReloadableDrawable
+ {
+ protected readonly IBindable Direction = new Bindable();
+
+ [Resolved(CanBeNull = true)]
+ private ManiaStage stage { get; set; }
+
+ public HitObjectArea(HitObjectContainer hitObjectContainer)
+ {
+ InternalChildren = new[]
+ {
+ hitObjectContainer,
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(IScrollingInfo scrollingInfo)
+ {
+ Direction.BindTo(scrollingInfo.Direction);
+ Direction.BindValueChanged(onDirectionChanged, true);
+ }
+
+ protected override void SkinChanged(ISkinSource skin, bool allowFallback)
+ {
+ base.SkinChanged(skin, allowFallback);
+ UpdateHitPosition();
+ }
+
+ private void onDirectionChanged(ValueChangedEvent direction)
+ {
+ UpdateHitPosition();
+ }
+
+ protected virtual void UpdateHitPosition()
+ {
+ float hitPosition = CurrentSkin.GetConfig(
+ new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HitPosition))?.Value
+ ?? ManiaStage.HIT_TARGET_POSITION;
+
+ Padding = Direction.Value == ScrollingDirection.Up
+ ? new MarginPadding { Top = hitPosition }
+ : new MarginPadding { Bottom = hitPosition };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
index bd21663c4e..c6102675a1 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
@@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd . 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.Allocation;
@@ -12,9 +11,11 @@ using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
+using osu.Game.Rulesets.Mania.UI.Components;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
+using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
@@ -33,15 +34,18 @@ namespace osu.Game.Rulesets.Mania.UI
public IReadOnlyList Columns => columnFlow.Children;
private readonly FillFlowContainer columnFlow;
- private readonly Container barLineContainer;
-
public Container Judgements => judgements;
private readonly JudgementContainer judgements;
+ private readonly Drawable barLineContainer;
private readonly Container topLevelContainer;
- private List normalColumnColours = new List();
- private Color4 specialColumnColour;
+ private readonly Dictionary columnColours = new Dictionary
+ {
+ { ColumnType.Even, new Color4(6, 84, 0, 255) },
+ { ColumnType.Odd, new Color4(94, 0, 57, 255) },
+ { ColumnType.Special, new Color4(0, 48, 63, 255) }
+ };
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Columns.Any(c => c.ReceivePositionalInputAt(screenSpacePos));
@@ -90,7 +94,6 @@ namespace osu.Game.Rulesets.Mania.UI
AutoSizeAxes = Axes.X,
Direction = FillDirection.Horizontal,
Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING },
- Spacing = new Vector2(COLUMN_SPACING, 0)
},
}
},
@@ -103,13 +106,12 @@ namespace osu.Game.Rulesets.Mania.UI
Width = 1366, // Bar lines should only be masked on the vertical axis
BypassAutoSizeAxes = Axes.Both,
Masking = true,
- Child = barLineContainer = new Container
+ Child = barLineContainer = new HitObjectArea(HitObjectContainer)
{
Name = "Bar lines",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Y,
- Child = HitObjectContainer
}
},
judgements = new JudgementContainer
@@ -126,24 +128,52 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < definition.Columns; i++)
{
- var isSpecial = definition.IsSpecialColumn(i);
+ var columnType = definition.GetTypeOfColumn(i);
var column = new Column(firstColumnIndex + i)
{
- IsSpecial = isSpecial,
- Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
+ ColumnType = columnType,
+ AccentColour = columnColours[columnType],
+ Action = { Value = columnType == ColumnType.Special ? specialColumnStartAction++ : normalColumnStartAction++ }
};
AddColumn(column);
}
+ }
- Direction.BindValueChanged(dir =>
+ private ISkin currentSkin;
+
+ [BackgroundDependencyLoader]
+ private void load(ISkinSource skin)
+ {
+ currentSkin = skin;
+ skin.SourceChanged += onSkinChanged;
+
+ onSkinChanged();
+ }
+
+ private void onSkinChanged()
+ {
+ foreach (var col in columnFlow)
{
- barLineContainer.Padding = new MarginPadding
+ if (col.Index > 0)
{
- Top = dir.NewValue == ScrollingDirection.Up ? HIT_TARGET_POSITION : 0,
- Bottom = dir.NewValue == ScrollingDirection.Down ? HIT_TARGET_POSITION : 0,
- };
- }, true);
+ float spacing = currentSkin.GetConfig(
+ new LegacyManiaSkinConfigurationLookup(Columns.Count, LegacyManiaSkinConfigurationLookups.ColumnSpacing, col.Index - 1))
+ ?.Value ?? COLUMN_SPACING;
+
+ col.Margin = new MarginPadding { Left = spacing };
+ }
+
+ float? width = currentSkin.GetConfig(
+ new LegacyManiaSkinConfigurationLookup(Columns.Count, LegacyManiaSkinConfigurationLookups.ColumnWidth, col.Index))
+ ?.Value;
+
+ if (width == null)
+ // only used by default skin (legacy skins get defaults set in LegacyManiaSkinConfiguration)
+ col.Width = col.IsSpecial ? Column.SPECIAL_COLUMN_WIDTH : Column.COLUMN_WIDTH;
+ else
+ col.Width = width.Value;
+ }
}
public void AddColumn(Column c)
@@ -196,38 +226,6 @@ namespace osu.Game.Rulesets.Mania.UI
});
}
- [BackgroundDependencyLoader]
- private void load()
- {
- normalColumnColours = new List
- {
- new Color4(94, 0, 57, 255),
- new Color4(6, 84, 0, 255)
- };
-
- specialColumnColour = new Color4(0, 48, 63, 255);
-
- // Set the special column + colour + key
- foreach (var column in Columns)
- {
- if (!column.IsSpecial)
- continue;
-
- column.AccentColour = specialColumnColour;
- }
-
- var nonSpecialColumns = Columns.Where(c => !c.IsSpecial).ToList();
-
- // We'll set the colours of the non-special columns in a separate loop, because the non-special
- // column colours are mirrored across their centre and special styles mess with this
- for (int i = 0; i < Math.Ceiling(nonSpecialColumns.Count / 2f); i++)
- {
- Color4 colour = normalColumnColours[i % normalColumnColours.Count];
- nonSpecialColumns[i].AccentColour = colour;
- nonSpecialColumns[nonSpecialColumns.Count - 1 - i].AccentColour = colour;
- }
- }
-
protected override void Update()
{
// Due to masking differences, it is not possible to get the width of the columns container automatically
diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs
index 8141108aef..c52183f3f2 100644
--- a/osu.Game/Rulesets/UI/Playfield.cs
+++ b/osu.Game/Rulesets/UI/Playfield.cs
@@ -10,7 +10,6 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Containers;
-using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osuTK;
@@ -62,10 +61,7 @@ namespace osu.Game.Rulesets.UI
hitObjectContainerLazy = new Lazy(CreateHitObjectContainer);
}
- [Resolved]
- private IBindable beatmap { get; set; }
-
- [Resolved]
+ [Resolved(CanBeNull = true)]
private IReadOnlyList mods { get; set; }
[BackgroundDependencyLoader]
@@ -137,7 +133,7 @@ namespace osu.Game.Rulesets.UI
{
base.Update();
- if (beatmap != null)
+ if (mods != null)
{
foreach (var mod in mods)
{
diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs
index 56d2652e76..0d0c4943ef 100644
--- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs
+++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs
@@ -14,6 +14,7 @@ namespace osu.Game.Skinning
public readonly float[] ColumnWidth;
public float HitPosition = 124.8f; // (480 - 402) * 1.6f
+ public float LightPosition = 107.2f; // (480 - 413) * 1.6f
public bool ShowJudgementLine = true;
public LegacyManiaSkinConfiguration(int keys)
diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs
index 72556a79b4..49e4faa269 100644
--- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs
+++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs
@@ -19,10 +19,13 @@ namespace osu.Game.Skinning
public enum LegacyManiaSkinConfigurationLookups
{
+ ColumnWidth,
+ ColumnSpacing,
LightImage,
LeftLineWidth,
RightLineWidth,
HitPosition,
+ LightPosition,
HitTargetImage,
ShowJudgementLine,
KeyImage,
diff --git a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs
index 2c6b76847d..dabdd0a980 100644
--- a/osu.Game/Skinning/LegacyManiaSkinDecoder.cs
+++ b/osu.Game/Skinning/LegacyManiaSkinDecoder.cs
@@ -91,6 +91,10 @@ namespace osu.Game.Skinning
currentConfig.HitPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * size_scale_factor;
break;
+ case "LightPosition":
+ currentConfig.LightPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * size_scale_factor;
+ break;
+
case "JudgementLine":
currentConfig.ShowJudgementLine = pair.Value == "1";
break;
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 94caa78e6d..eafbdd4ee5 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using JetBrains.Annotations;
@@ -120,18 +121,29 @@ namespace osu.Game.Skinning
case SkinCustomColourLookup customColour:
return SkinUtils.As(getCustomColour(customColour.Lookup.ToString()));
- case LegacyManiaSkinConfigurationLookup legacy:
+ case LegacyManiaSkinConfigurationLookup maniaLookup:
if (!AllowManiaSkin)
return null;
- if (!maniaConfigurations.TryGetValue(legacy.Keys, out var existing))
- maniaConfigurations[legacy.Keys] = existing = new LegacyManiaSkinConfiguration(legacy.Keys);
+ if (!maniaConfigurations.TryGetValue(maniaLookup.Keys, out var existing))
+ maniaConfigurations[maniaLookup.Keys] = existing = new LegacyManiaSkinConfiguration(maniaLookup.Keys);
- switch (legacy.Lookup)
+ switch (maniaLookup.Lookup)
{
+ case LegacyManiaSkinConfigurationLookups.ColumnWidth:
+ Debug.Assert(maniaLookup.TargetColumn != null);
+ return SkinUtils.As(new Bindable(existing.ColumnWidth[maniaLookup.TargetColumn.Value]));
+
+ case LegacyManiaSkinConfigurationLookups.ColumnSpacing:
+ Debug.Assert(maniaLookup.TargetColumn != null);
+ return SkinUtils.As(new Bindable(existing.ColumnSpacing[maniaLookup.TargetColumn.Value]));
+
case LegacyManiaSkinConfigurationLookups.HitPosition:
return SkinUtils.As(new Bindable(existing.HitPosition));
+ case LegacyManiaSkinConfigurationLookups.LightPosition:
+ return SkinUtils.As(new Bindable(existing.LightPosition));
+
case LegacyManiaSkinConfigurationLookups.ShowJudgementLine:
return SkinUtils.As(new Bindable(existing.ShowJudgementLine));
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 30c11a1cdb..4a9d2e0830 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index d035f5c4d8..a528bd5658 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -71,7 +71,7 @@
-
+
@@ -79,7 +79,7 @@
-
+