1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-06 11:02:54 +08:00

Merge branch 'master' into mania-existence-check

This commit is contained in:
Dean Herbert 2020-04-01 23:11:09 +09:00 committed by GitHub
commit 1446b0782b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 334 additions and 171 deletions

View File

@ -52,6 +52,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.401.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,50 @@
// 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 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<ColumnType> expected, int columns)
{
var definition = new StageDefinition
{
Columns = columns
};
var results = getResults(definition);
Assert.AreEqual(expected, results);
}
private IEnumerable<ColumnType> getResults(StageDefinition definition)
{
for (var i = 0; i < definition.Columns; i++)
yield return definition.GetTypeOfColumn(i);
}
}
}

View File

@ -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)

View File

@ -0,0 +1,27 @@
// 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.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)
};
});
}
}
}

View File

@ -0,0 +1,12 @@
// 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.
namespace osu.Game.Rulesets.Mania.Beatmaps
{
public enum ColumnType
{
Even,
Odd,
Special
}
}

View File

@ -1,6 +1,7 @@
// 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;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Beatmaps
@ -21,5 +22,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// <param name="column">The 0-based column index.</param>
/// <returns>Whether the column is a special column.</returns>
public bool IsSpecialColumn(int column) => Columns % 2 == 1 && column == Columns / 2;
/// <summary>
/// Get the type of column given a column index.
/// </summary>
/// <param name="column">The 0-based column index.</param>
/// <returns>The type of the column.</returns>
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;
}
}
}

View File

@ -35,8 +35,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject)
{
string imageName = skin.GetConfig<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage, column.Index))?.Value
string imageName = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value
?? $"mania-note{FallbackColumnIndex}L";
sprite = skin.GetAnimation(imageName, true, true).With(d =>

View File

@ -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<ManiaAction>
public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler<ManiaAction>
{
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
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<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightImage, 0))?.Value
string lightImage = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.LightImage, 0)?.Value
?? "mania-stage-light";
float leftLineWidth = skin.GetConfig<LegacyManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LeftLineWidth, column.Index))
?.Value ?? 1;
float rightLineWidth = skin.GetConfig<LegacyManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.RightLineWidth, column.Index))
?.Value ?? 1;
float leftLineWidth = GetManiaSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LeftLineWidth)
?.Value ?? 1;
float rightLineWidth = GetManiaSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.RightLineWidth)
?.Value ?? 1;
bool hasLeftLine = leftLineWidth > 0;
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(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<LegacyManiaSkinConfigurationLookup, float>(
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);

View File

@ -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<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
[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<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HitTargetImage))?.Value
string targetImage = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.HitTargetImage)?.Value
?? "mania-stage-hint";
bool showJudgementLine = skin.GetConfig<LegacyManiaSkinConfigurationLookup, bool>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.ShowJudgementLine))?.Value
bool showJudgementLine = GetManiaSkinConfig<bool>(skin, LegacyManiaSkinConfigurationLookups.ShowJudgementLine)?.Value
?? true;
InternalChild = directionContainer = new Container

View File

@ -36,12 +36,10 @@ namespace osu.Game.Rulesets.Mania.Skinning
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
{
string upImage = skin.GetConfig<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.KeyImage, column.Index))?.Value
string upImage = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.KeyImage)?.Value
?? $"mania-key{FallbackColumnIndex}";
string downImage = skin.GetConfig<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.KeyImageDown, column.Index))?.Value
string downImage = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.KeyImageDown)?.Value
?? $"mania-key{FallbackColumnIndex}D";
InternalChild = directionContainer = new Container

View File

@ -1,41 +1,48 @@
// 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;
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
{
/// <summary>
/// A <see cref="CompositeDrawable"/> which is placed somewhere within a <see cref="Column"/>.
/// </summary>
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; }
/// <summary>
/// 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.
/// </summary>
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<T> GetManiaSkinConfig<T>(ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? index = null)
=> base.GetManiaSkinConfig<T>(skin, lookup, index ?? Column.Index);
}
}

View File

@ -0,0 +1,32 @@
// 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 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
{
/// <summary>
/// A mania legacy skin element.
/// </summary>
public class LegacyManiaElement : CompositeDrawable
{
[Resolved(CanBeNull = true)]
[CanBeNull]
protected ManiaStage Stage { get; private set; }
/// <summary>
/// Retrieve a per-column-count skin configuration.
/// </summary>
/// <param name="skin">The skin from which configuration is retrieved.</param>
/// <param name="lookup">The value to retrieve.</param>
/// <param name="index">If not null, denotes the index of the column to which the entry applies.</param>
protected virtual IBindable<T> GetManiaSkinConfig<T>(ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? index = null)
=> skin.GetConfig<LegacyManiaSkinConfigurationLookup, T>(
new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, lookup, index));
}
}

View File

@ -83,8 +83,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
break;
}
string noteImage = skin.GetConfig<LegacyManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, lookup, Column.Index))?.Value
string noteImage = GetManiaSkinConfig<string>(skin, lookup)?.Value
?? $"mania-note{FallbackColumnIndex}{suffix}";
return skin.GetTexture(noteImage);

View File

@ -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<ManiaAction>, IHasAccentColour
{
public const float COLUMN_WIDTH = 80;
private const float special_column_width = 70;
public const float SPECIAL_COLUMN_WIDTH = 70;
/// <summary>
/// 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; }

View File

@ -1,8 +1,6 @@
// 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.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<HitExplosion> Explosions;
[Resolved(CanBeNull = true)]
private ManiaStage stage { get; set; }
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
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<HitExplosion> { RelativeSizeAxes = Axes.Both }
};
Explosions = new Container<HitExplosion>
{
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<ScrollingDirection> direction)
{
updateHitPosition();
}
private void updateHitPosition()
{
float hitPosition = CurrentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>(
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 };
}
}
}

View File

@ -0,0 +1,57 @@
// 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.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<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
[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<ScrollingDirection> direction)
{
UpdateHitPosition();
}
protected virtual void UpdateHitPosition()
{
float hitPosition = CurrentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>(
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 };
}
}
}

View File

@ -1,7 +1,6 @@
// 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;
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<Column> Columns => columnFlow.Children;
private readonly FillFlowContainer<Column> columnFlow;
private readonly Container barLineContainer;
public Container<DrawableManiaJudgement> Judgements => judgements;
private readonly JudgementContainer<DrawableManiaJudgement> judgements;
private readonly Drawable barLineContainer;
private readonly Container topLevelContainer;
private List<Color4> normalColumnColours = new List<Color4>();
private Color4 specialColumnColour;
private readonly Dictionary<ColumnType, Color4> columnColours = new Dictionary<ColumnType, Color4>
{
{ 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<DrawableManiaJudgement>
@ -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<LegacyManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(Columns.Count, LegacyManiaSkinConfigurationLookups.ColumnSpacing, col.Index - 1))
?.Value ?? COLUMN_SPACING;
col.Margin = new MarginPadding { Left = spacing };
}
float? width = currentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>(
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<Color4>
{
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

View File

@ -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<HitObjectContainer>(CreateHitObjectContainer);
}
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; }
[Resolved]
[Resolved(CanBeNull = true)]
private IReadOnlyList<Mod> 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)
{

View File

@ -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)

View File

@ -19,10 +19,13 @@ namespace osu.Game.Skinning
public enum LegacyManiaSkinConfigurationLookups
{
ColumnWidth,
ColumnSpacing,
LightImage,
LeftLineWidth,
RightLineWidth,
HitPosition,
LightPosition,
HitTargetImage,
ShowJudgementLine,
KeyImage,

View File

@ -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;

View File

@ -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<TValue>(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<TValue>(new Bindable<float>(existing.ColumnWidth[maniaLookup.TargetColumn.Value]));
case LegacyManiaSkinConfigurationLookups.ColumnSpacing:
Debug.Assert(maniaLookup.TargetColumn != null);
return SkinUtils.As<TValue>(new Bindable<float>(existing.ColumnSpacing[maniaLookup.TargetColumn.Value]));
case LegacyManiaSkinConfigurationLookups.HitPosition:
return SkinUtils.As<TValue>(new Bindable<float>(existing.HitPosition));
case LegacyManiaSkinConfigurationLookups.LightPosition:
return SkinUtils.As<TValue>(new Bindable<float>(existing.LightPosition));
case LegacyManiaSkinConfigurationLookups.ShowJudgementLine:
return SkinUtils.As<TValue>(new Bindable<bool>(existing.ShowJudgementLine));
}

View File

@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.401.0" />
<PackageReference Include="Sentry" Version="2.1.1" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" />

View File

@ -71,7 +71,7 @@
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.401.0" />
</ItemGroup>
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
<ItemGroup Label="Transitive Dependencies">
@ -79,7 +79,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2020.331.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.401.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />