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

Merge branch 'master' into fix-convert-scroll-speed

This commit is contained in:
Dean Herbert 2020-04-03 22:47:53 +09:00 committed by GitHub
commit eacbb20d87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 390 additions and 137 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="RiderProjectSettingsUpdater"> <component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="1" /> <option name="vcsConfiguration" value="2" />
</component> </component>
</project> </project>

View File

@ -51,7 +51,7 @@
<Reference Include="Java.Interop" /> <Reference Include="Java.Interop" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.402.1" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2020.403.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.402.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2020.403.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Catch
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new CatchLegacySkinTransformer(source); public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new CatchLegacySkinTransformer(source);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score);

View File

@ -384,7 +384,7 @@ namespace osu.Game.Rulesets.Catch.UI
} }
currentCatcher.Show(); currentCatcher.Show();
(currentCatcher.Drawable as IAnimation)?.GotoFrame(0); (currentCatcher.Drawable as IFramedAnimation)?.GotoFrame(0);
} }
private void beginTrail() private void beginTrail()

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground, 0), _ => new DefaultColumnBackground())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
} }
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground, 0), _ => new DefaultColumnBackground())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
} }

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new ColumnHitObjectArea(new HitObjectContainer()) Child = new ColumnHitObjectArea(0, new HitObjectContainer())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
} }
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new ColumnHitObjectArea(new HitObjectContainer()) Child = new ColumnHitObjectArea(1, new HitObjectContainer())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
} }

View File

@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
CreatedDrawables.OfType<Container>().ForEach(c => CreatedDrawables.OfType<Container>().ForEach(c =>
{ {
c.Add(new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), c.Add(new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion, 0),
_ => new DefaultHitExplosion((runcount / 15) % 2 == 0 ? new Color4(94, 0, 57, 255) : new Color4(6, 84, 0, 255), runcount % 6 != 0) _ => new DefaultHitExplosion((runcount / 15) % 2 == 0 ? new Color4(94, 0, 57, 255) : new Color4(6, 84, 0, 255), runcount % 6 != 0)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,

View File

@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea, 0), _ => new DefaultKeyArea())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
}, },
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Width = 0.5f, Width = 0.5f,
Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea, 1), _ => new DefaultKeyArea())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
}, },

View File

@ -0,0 +1,52 @@
// 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 NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
public class TestScenePlayfield : ManiaSkinnableTestScene
{
private List<StageDefinition> stageDefinitions = new List<StageDefinition>();
[Test]
public void TestSingleStage()
{
AddStep("create stage", () =>
{
stageDefinitions = new List<StageDefinition>
{
new StageDefinition { Columns = 2 }
};
SetContents(() => new ManiaPlayfield(stageDefinitions));
});
}
[Test]
public void TestDualStages()
{
AddStep("create stage", () =>
{
stageDefinitions = new List<StageDefinition>
{
new StageDefinition { Columns = 2 },
new StageDefinition { Columns = 2 }
};
SetContents(() => new ManiaPlayfield(stageDefinitions));
});
}
protected override IBeatmap CreateBeatmapForSkinProvider()
{
var maniaBeatmap = (ManiaBeatmap)base.CreateBeatmapForSkinProvider();
maniaBeatmap.Stages = stageDefinitions;
return maniaBeatmap;
}
}
}

View File

@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania
public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this); public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this);
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new ManiaLegacySkinTransformer(source); public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new ManiaLegacySkinTransformer(source, beatmap);
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods) public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
{ {

View File

@ -1,15 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania namespace osu.Game.Rulesets.Mania
{ {
public class ManiaSkinComponent : GameplaySkinComponent<ManiaSkinComponents> public class ManiaSkinComponent : GameplaySkinComponent<ManiaSkinComponents>
{ {
public ManiaSkinComponent(ManiaSkinComponents component) /// <summary>
/// The intended <see cref="Column"/> index for this component.
/// May be null if the component does not exist in a <see cref="Column"/>.
/// </summary>
public readonly int? TargetColumn;
/// <summary>
/// Creates a new <see cref="ManiaSkinComponent"/>.
/// </summary>
/// <param name="component">The component.</param>
/// <param name="targetColumn">The intended <see cref="Column"/> index for this component. May be null if the component does not exist in a <see cref="Column"/>.</param>
public ManiaSkinComponent(ManiaSkinComponents component, int? targetColumn = null)
: base(component) : base(component)
{ {
TargetColumn = targetColumn;
} }
protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME; protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME;

View File

@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddRangeInternal(new[] AddRangeInternal(new[]
{ {
bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece()) bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody, hitObject.Column), _ => new DefaultBodyPiece())
{ {
RelativeSizeAxes = Axes.X RelativeSizeAxes = Axes.X
}, },

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponent(Component), _ => new DefaultNotePiece()) AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponent(Component, hitObject.Column), _ => new DefaultNotePiece())
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y AutoSizeAxes = Axes.Y

View File

@ -6,7 +6,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Animations;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning; using osu.Game.Skinning;
@ -21,12 +20,6 @@ namespace osu.Game.Rulesets.Mania.Skinning
private Drawable sprite; private Drawable sprite;
[Resolved(CanBeNull = true)]
private ManiaStage stage { get; set; }
[Resolved]
private Column column { get; set; }
public LegacyBodyPiece() public LegacyBodyPiece()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;

View File

@ -18,12 +18,14 @@ namespace osu.Game.Rulesets.Mania.Skinning
public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler<ManiaAction> public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler<ManiaAction>
{ {
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
private readonly bool isLastColumn;
private Container lightContainer; private Container lightContainer;
private Sprite light; private Sprite light;
public LegacyColumnBackground() public LegacyColumnBackground(bool isLastColumn)
{ {
this.isLastColumn = isLastColumn;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
} }
@ -40,10 +42,9 @@ namespace osu.Game.Rulesets.Mania.Skinning
bool hasLeftLine = leftLineWidth > 0; bool hasLeftLine = leftLineWidth > 0;
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m
|| Stage == null || Column.Index == Stage.Columns.Count - 1; || isLastColumn;
float lightPosition = skin.GetConfig<LegacyManiaSkinConfigurationLookup, float>( float lightPosition = GetManiaSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value
new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightPosition))?.Value
?? 0; ?? 0;
Color4 lineColour = GetManiaSkinConfig<Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLineColour)?.Value Color4 lineColour = GetManiaSkinConfig<Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLineColour)?.Value

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
// This animation is discarded and re-queried with the appropriate frame length afterwards. // This animation is discarded and re-queried with the appropriate frame length afterwards.
var tmp = skin.GetAnimation(imageName, true, false); var tmp = skin.GetAnimation(imageName, true, false);
double frameLength = 0; double frameLength = 0;
if (tmp is IAnimation tmpAnimation && tmpAnimation.FrameCount > 0) if (tmp is IFramedAnimation tmpAnimation && tmpAnimation.FrameCount > 0)
frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount); frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount);
explosion = skin.GetAnimation(imageName, true, false, startAtCurrentTime: true, frameLength: frameLength).With(d => explosion = skin.GetAnimation(imageName, true, false, startAtCurrentTime: true, frameLength: frameLength).With(d =>

View File

@ -22,9 +22,6 @@ namespace osu.Game.Rulesets.Mania.Skinning
private Sprite upSprite; private Sprite upSprite;
private Sprite downSprite; private Sprite downSprite;
[Resolved(CanBeNull = true)]
private ManiaStage stage { get; set; }
[Resolved] [Resolved]
private Column column { get; set; } private Column column { get; set; }

View File

@ -1,11 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // 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.Bindables;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.Skinning namespace osu.Game.Rulesets.Mania.Skinning
@ -15,10 +12,6 @@ namespace osu.Game.Rulesets.Mania.Skinning
/// </summary> /// </summary>
public class LegacyManiaElement : CompositeDrawable public class LegacyManiaElement : CompositeDrawable
{ {
[Resolved(CanBeNull = true)]
[CanBeNull]
protected ManiaStage Stage { get; private set; }
/// <summary> /// <summary>
/// Retrieve a per-column-count skin configuration. /// Retrieve a per-column-count skin configuration.
/// </summary> /// </summary>
@ -26,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
/// <param name="lookup">The value to retrieve.</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> /// <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) protected virtual IBindable<T> GetManiaSkinConfig<T>(ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? index = null)
=> skin.GetConfig<LegacyManiaSkinConfigurationLookup, T>( => skin.GetConfig<ManiaSkinConfigurationLookup, T>(
new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, lookup, index)); new ManiaSkinConfigurationLookup(lookup, index));
} }
} }

View File

@ -8,6 +8,8 @@ using osu.Framework.Audio.Sample;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.Skinning namespace osu.Game.Rulesets.Mania.Skinning
@ -15,6 +17,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
public class ManiaLegacySkinTransformer : ISkin public class ManiaLegacySkinTransformer : ISkin
{ {
private readonly ISkin source; private readonly ISkin source;
private readonly ManiaBeatmap beatmap;
private Lazy<bool> isLegacySkin; private Lazy<bool> isLegacySkin;
@ -24,9 +27,10 @@ namespace osu.Game.Rulesets.Mania.Skinning
/// </summary> /// </summary>
private Lazy<bool> hasKeyTexture; private Lazy<bool> hasKeyTexture;
public ManiaLegacySkinTransformer(ISkinSource source) public ManiaLegacySkinTransformer(ISkinSource source, IBeatmap beatmap)
{ {
this.source = source; this.source = source;
this.beatmap = (ManiaBeatmap)beatmap;
source.SourceChanged += sourceChanged; source.SourceChanged += sourceChanged;
sourceChanged(); sourceChanged();
@ -36,8 +40,8 @@ namespace osu.Game.Rulesets.Mania.Skinning
{ {
isLegacySkin = new Lazy<bool>(() => source.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version) != null); isLegacySkin = new Lazy<bool>(() => source.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version) != null);
hasKeyTexture = new Lazy<bool>(() => source.GetAnimation( hasKeyTexture = new Lazy<bool>(() => source.GetAnimation(
source.GetConfig<LegacyManiaSkinConfigurationLookup, string>( source.GetConfig<ManiaSkinConfigurationLookup, string>(
new LegacyManiaSkinConfigurationLookup(4, LegacyManiaSkinConfigurationLookups.KeyImage, 0))?.Value new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.KeyImage, 0))?.Value
?? "mania-key1", true, true) != null); ?? "mania-key1", true, true) != null);
} }
@ -55,7 +59,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
switch (maniaComponent.Component) switch (maniaComponent.Component)
{ {
case ManiaSkinComponents.ColumnBackground: case ManiaSkinComponents.ColumnBackground:
return new LegacyColumnBackground(); return new LegacyColumnBackground(maniaComponent.TargetColumn == beatmap.TotalColumns - 1);
case ManiaSkinComponents.HitTarget: case ManiaSkinComponents.HitTarget:
return new LegacyHitTarget(); return new LegacyHitTarget();
@ -115,7 +119,12 @@ namespace osu.Game.Rulesets.Mania.Skinning
public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample); public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample);
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
source.GetConfig<TLookup, TValue>(lookup); {
if (lookup is ManiaSkinConfigurationLookup maniaLookup)
return source.GetConfig<LegacyManiaSkinConfigurationLookup, TValue>(new LegacyManiaSkinConfigurationLookup(beatmap.TotalColumns, maniaLookup.Lookup, maniaLookup.TargetColumn));
return source.GetConfig<TLookup, TValue>(lookup);
}
} }
} }

View File

@ -0,0 +1,33 @@
// 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.Game.Rulesets.Mania.UI;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania.Skinning
{
public class ManiaSkinConfigurationLookup
{
/// <summary>
/// The configuration lookup value.
/// </summary>
public readonly LegacyManiaSkinConfigurationLookups Lookup;
/// <summary>
/// The intended <see cref="Column"/> index for the configuration.
/// May be null if the configuration does not apply to a <see cref="Column"/>.
/// </summary>
public readonly int? TargetColumn;
/// <summary>
/// Creates a new <see cref="ManiaSkinConfigurationLookup"/>.
/// </summary>
/// <param name="lookup">The lookup value.</param>
/// <param name="targetColumn">The intended <see cref="Column"/> index for the configuration. May be null if the configuration does not apply to a <see cref="Column"/>.</param>
public ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups lookup, int? targetColumn = null)
{
Lookup = lookup;
TargetColumn = targetColumn;
}
}
}

View File

@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.UI
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground, Index), _ => new DefaultColumnBackground())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
}; };
@ -52,8 +52,8 @@ namespace osu.Game.Rulesets.Mania.UI
{ {
// For input purposes, the background is added at the highest depth, but is then proxied back below all other elements // For input purposes, the background is added at the highest depth, but is then proxied back below all other elements
background.CreateProxy(), background.CreateProxy(),
hitObjectArea = new ColumnHitObjectArea(HitObjectContainer) { RelativeSizeAxes = Axes.Both }, hitObjectArea = new ColumnHitObjectArea(Index, HitObjectContainer) { RelativeSizeAxes = Axes.Both },
new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea, Index), _ => new DefaultKeyArea())
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both
}, },
@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.UI
if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value) if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value)
return; return;
var explosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), _ => var explosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion, Index), _ =>
new DefaultHitExplosion(judgedObject.AccentColour.Value, judgedObject is DrawableHoldNoteTick)) new DefaultHitExplosion(judgedObject.AccentColour.Value, judgedObject is DrawableHoldNoteTick))
{ {
RelativeSizeAxes = Axes.Both RelativeSizeAxes = Axes.Both

View File

@ -14,12 +14,12 @@ namespace osu.Game.Rulesets.Mania.UI.Components
public readonly Container Explosions; public readonly Container Explosions;
private readonly Drawable hitTarget; private readonly Drawable hitTarget;
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer) public ColumnHitObjectArea(int columnIndex, HitObjectContainer hitObjectContainer)
: base(hitObjectContainer) : base(hitObjectContainer)
{ {
AddRangeInternal(new[] AddRangeInternal(new[]
{ {
hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget, columnIndex), _ => new DefaultHitTarget())
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Depth = 1 Depth = 1

View File

@ -4,6 +4,7 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Skinning;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning; using osu.Game.Skinning;
@ -14,9 +15,6 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{ {
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
[Resolved(CanBeNull = true)]
private ManiaStage stage { get; set; }
public HitObjectArea(HitObjectContainer hitObjectContainer) public HitObjectArea(HitObjectContainer hitObjectContainer)
{ {
InternalChildren = new[] InternalChildren = new[]
@ -45,8 +43,8 @@ namespace osu.Game.Rulesets.Mania.UI.Components
protected virtual void UpdateHitPosition() protected virtual void UpdateHitPosition()
{ {
float hitPosition = CurrentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>( float hitPosition = CurrentSkin.GetConfig<ManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.HitPosition))?.Value new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.HitPosition))?.Value
?? ManiaStage.HIT_TARGET_POSITION; ?? ManiaStage.HIT_TARGET_POSITION;
Padding = Direction.Value == ScrollingDirection.Up Padding = Direction.Value == ScrollingDirection.Up

View File

@ -11,6 +11,7 @@ using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Skinning;
using osu.Game.Rulesets.Mania.UI.Components; using osu.Game.Rulesets.Mania.UI.Components;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
@ -24,7 +25,6 @@ namespace osu.Game.Rulesets.Mania.UI
/// <summary> /// <summary>
/// A collection of <see cref="Column"/>s. /// A collection of <see cref="Column"/>s.
/// </summary> /// </summary>
[Cached]
public class ManiaStage : ScrollingPlayfield public class ManiaStage : ScrollingPlayfield
{ {
public const float COLUMN_SPACING = 1; public const float COLUMN_SPACING = 1;
@ -146,15 +146,15 @@ namespace osu.Game.Rulesets.Mania.UI
{ {
if (col.Index > 0) if (col.Index > 0)
{ {
float spacing = currentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>( float spacing = currentSkin.GetConfig<ManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(Columns.Count, LegacyManiaSkinConfigurationLookups.ColumnSpacing, col.Index - 1)) new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnSpacing, col.Index - 1))
?.Value ?? COLUMN_SPACING; ?.Value ?? COLUMN_SPACING;
col.Margin = new MarginPadding { Left = spacing }; col.Margin = new MarginPadding { Left = spacing };
} }
float? width = currentSkin.GetConfig<LegacyManiaSkinConfigurationLookup, float>( float? width = currentSkin.GetConfig<ManiaSkinConfigurationLookup, float>(
new LegacyManiaSkinConfigurationLookup(Columns.Count, LegacyManiaSkinConfigurationLookups.ColumnWidth, col.Index)) new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.ColumnWidth, col.Index))
?.Value; ?.Value;
if (width == null) if (width == null)

View File

@ -179,7 +179,7 @@ namespace osu.Game.Rulesets.Osu
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this); public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new OsuLegacySkinTransformer(source); public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new OsuLegacySkinTransformer(source);
public int LegacyID => 0; public int LegacyID => 0;

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -4,31 +4,28 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osuTK; using osuTK;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Taiko.Audio;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests namespace osu.Game.Rulesets.Taiko.Tests
{ {
[TestFixture] [TestFixture]
public class TestSceneInputDrum : OsuTestScene public class TestSceneInputDrum : SkinnableTestScene
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(InputDrum), typeof(InputDrum),
typeof(DrumSampleMapping),
typeof(HitSampleInfo),
typeof(SampleControlPoint)
}; };
public TestSceneInputDrum() [BackgroundDependencyLoader]
private void load()
{ {
Add(new TaikoInputManager(new RulesetInfo { ID = 1 }) SetContents(() => new TaikoInputManager(new RulesetInfo { ID = 1 })
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = new Container Child = new Container

View File

@ -0,0 +1,144 @@
// 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.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Taiko.Audio;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Taiko.Skinning
{
/// <summary>
/// A component of the playfield that captures input and displays input as a drum.
/// </summary>
internal class LegacyInputDrum : Container
{
public LegacyInputDrum()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
Children = new Drawable[]
{
new Sprite
{
Texture = skin.GetTexture("taiko-bar-left")
},
new LegacyHalfDrum(false)
{
Name = "Left Half",
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
RimAction = TaikoAction.LeftRim,
CentreAction = TaikoAction.LeftCentre
},
new LegacyHalfDrum(true)
{
Name = "Right Half",
Anchor = Anchor.TopRight,
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
Scale = new Vector2(-1, 1),
RimAction = TaikoAction.RightRim,
CentreAction = TaikoAction.RightCentre
}
};
}
/// <summary>
/// A half-drum. Contains one centre and one rim hit.
/// </summary>
private class LegacyHalfDrum : Container, IKeyBindingHandler<TaikoAction>
{
/// <summary>
/// The key to be used for the rim of the half-drum.
/// </summary>
public TaikoAction RimAction;
/// <summary>
/// The key to be used for the centre of the half-drum.
/// </summary>
public TaikoAction CentreAction;
private readonly Sprite rimHit;
private readonly Sprite centreHit;
[Resolved]
private DrumSampleMapping sampleMappings { get; set; }
public LegacyHalfDrum(bool flipped)
{
Masking = true;
Children = new Drawable[]
{
rimHit = new Sprite
{
Anchor = flipped ? Anchor.CentreRight : Anchor.CentreLeft,
Origin = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
Scale = new Vector2(-1, 1),
Alpha = 0,
},
centreHit = new Sprite
{
Anchor = flipped ? Anchor.CentreRight : Anchor.CentreLeft,
Origin = flipped ? Anchor.CentreRight : Anchor.CentreLeft,
Alpha = 0,
}
};
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
rimHit.Texture = skin.GetTexture(@"taiko-drum-outer");
centreHit.Texture = skin.GetTexture(@"taiko-drum-inner");
}
public bool OnPressed(TaikoAction action)
{
Drawable target = null;
var drumSample = sampleMappings.SampleAt(Time.Current);
if (action == CentreAction)
{
target = centreHit;
drumSample.Centre?.Play();
}
else if (action == RimAction)
{
target = rimHit;
drumSample.Rim?.Play();
}
if (target != null)
{
const float alpha_amount = 1;
const float down_time = 80;
const float up_time = 50;
target.Animate(
t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time)
).Then(
t => t.FadeOut(up_time)
);
}
return false;
}
public void OnReleased(TaikoAction action)
{
}
}
}
}

View File

@ -20,7 +20,22 @@ namespace osu.Game.Rulesets.Taiko.Skinning
this.source = source; this.source = source;
} }
public Drawable GetDrawableComponent(ISkinComponent component) => source.GetDrawableComponent(component); public Drawable GetDrawableComponent(ISkinComponent component)
{
if (!(component is TaikoSkinComponent taikoComponent))
return null;
switch (taikoComponent.Component)
{
case TaikoSkinComponents.InputDrum:
if (GetTexture("taiko-bar-left") != null)
return new LegacyInputDrum();
return null;
}
return source.GetDrawableComponent(component);
}
public Texture GetTexture(string componentName) => source.GetTexture(componentName); public Texture GetTexture(string componentName) => source.GetTexture(componentName);

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap, this); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap, this);
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new TaikoLegacySkinTransformer(source); public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new TaikoLegacySkinTransformer(source);
public const string SHORT_NAME = "taiko"; public const string SHORT_NAME = "taiko";

View File

@ -5,5 +5,6 @@ namespace osu.Game.Rulesets.Taiko
{ {
public enum TaikoSkinComponents public enum TaikoSkinComponents
{ {
InputDrum,
} }
} }

View File

@ -12,6 +12,7 @@ using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Audio; using osu.Game.Rulesets.Taiko.Audio;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.UI namespace osu.Game.Rulesets.Taiko.UI
{ {
@ -22,11 +23,12 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
private const float middle_split = 0.025f; private const float middle_split = 0.025f;
private readonly ControlPointInfo controlPoints; [Cached]
private DrumSampleMapping sampleMapping;
public InputDrum(ControlPointInfo controlPoints) public InputDrum(ControlPointInfo controlPoints)
{ {
this.controlPoints = controlPoints; sampleMapping = new DrumSampleMapping(controlPoints);
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit; FillMode = FillMode.Fit;
@ -35,35 +37,37 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
var sampleMappings = new DrumSampleMapping(controlPoints); Child = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new Container
Children = new Drawable[]
{ {
new TaikoHalfDrum(false, sampleMappings) RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{ {
Name = "Left Half", new TaikoHalfDrum(false)
Anchor = Anchor.Centre, {
Origin = Anchor.CentreRight, Name = "Left Half",
RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre,
RelativePositionAxes = Axes.X, Origin = Anchor.CentreRight,
X = -middle_split / 2, RelativeSizeAxes = Axes.Both,
RimAction = TaikoAction.LeftRim, RelativePositionAxes = Axes.X,
CentreAction = TaikoAction.LeftCentre X = -middle_split / 2,
}, RimAction = TaikoAction.LeftRim,
new TaikoHalfDrum(true, sampleMappings) CentreAction = TaikoAction.LeftCentre
{ },
Name = "Right Half", new TaikoHalfDrum(true)
Anchor = Anchor.Centre, {
Origin = Anchor.CentreLeft, Name = "Right Half",
RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre,
RelativePositionAxes = Axes.X, Origin = Anchor.CentreLeft,
X = middle_split / 2, RelativeSizeAxes = Axes.Both,
RimAction = TaikoAction.RightRim, RelativePositionAxes = Axes.X,
CentreAction = TaikoAction.RightCentre X = middle_split / 2,
RimAction = TaikoAction.RightRim,
CentreAction = TaikoAction.RightCentre
}
} }
}; });
AddRangeInternal(sampleMappings.Sounds); AddRangeInternal(sampleMapping.Sounds);
} }
/// <summary> /// <summary>
@ -86,12 +90,11 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly Sprite centre; private readonly Sprite centre;
private readonly Sprite centreHit; private readonly Sprite centreHit;
private readonly DrumSampleMapping sampleMappings; [Resolved]
private DrumSampleMapping sampleMappings { get; set; }
public TaikoHalfDrum(bool flipped, DrumSampleMapping sampleMappings) public TaikoHalfDrum(bool flipped)
{ {
this.sampleMappings = sampleMappings;
Masking = true; Masking = true;
Children = new Drawable[] Children = new Drawable[]

View File

@ -22,7 +22,6 @@ namespace osu.Game.Tests.Visual.Menus
{ {
typeof(StartupScreen), typeof(StartupScreen),
typeof(IntroScreen), typeof(IntroScreen),
typeof(OsuScreen),
typeof(IntroTestScene), typeof(IntroTestScene),
}; };

View File

@ -16,7 +16,7 @@ namespace osu.Game.Tournament.Components
{ {
private readonly string filename; private readonly string filename;
private readonly bool drawFallbackGradient; private readonly bool drawFallbackGradient;
private VideoSprite video; private Video video;
private ManualClock manualClock; private ManualClock manualClock;
@ -33,7 +33,7 @@ namespace osu.Game.Tournament.Components
if (stream != null) if (stream != null)
{ {
InternalChild = video = new VideoSprite(stream, false) InternalChild = video = new Video(stream, false)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit, FillMode = FillMode.Fit,

View File

@ -102,7 +102,7 @@ namespace osu.Game.Rulesets
public ModAutoplay GetAutoplayMod() => GetAllMods().OfType<ModAutoplay>().First(); public ModAutoplay GetAutoplayMod() => GetAllMods().OfType<ModAutoplay>().First();
public virtual ISkin CreateLegacySkinProvider(ISkinSource source) => null; public virtual ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => null;
protected Ruleset() protected Ruleset()
{ {

View File

@ -25,7 +25,7 @@ namespace osu.Game.Screens.Edit.Compose
// the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
// full access to all skin sources. // full access to all skin sources.
var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider)); var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, EditorBeatmap.PlayableBeatmap));
// load the skinning hierarchy first. // load the skinning hierarchy first.
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources. // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.

View File

@ -270,10 +270,9 @@ namespace osu.Game.Screens.Menu
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
InternalChild = new VideoSprite(videoStream, false) InternalChild = new Video(videoStream, false)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Clock = new FramedOffsetClock(Clock) { Offset = -logo_1 }
}; };
} }
} }

View File

@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play
dependencies.CacheAs(gameplayBeatmap); dependencies.CacheAs(gameplayBeatmap);
addUnderlayComponents(GameplayClockContainer); addUnderlayComponents(GameplayClockContainer);
addGameplayComponents(GameplayClockContainer, Beatmap.Value); addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap);
addOverlayComponents(GameplayClockContainer, Beatmap.Value); addOverlayComponents(GameplayClockContainer, Beatmap.Value);
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true);
@ -214,13 +214,13 @@ namespace osu.Game.Screens.Play
target.Add(DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both }); target.Add(DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both });
} }
private void addGameplayComponents(Container target, WorkingBeatmap working) private void addGameplayComponents(Container target, WorkingBeatmap working, IBeatmap playableBeatmap)
{ {
var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin); var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin);
// the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
// full access to all skin sources. // full access to all skin sources.
var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider)); var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap));
// load the skinning hierarchy first. // load the skinning hierarchy first.
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources. // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Timing;
namespace osu.Game.Skinning namespace osu.Game.Skinning
{ {
@ -28,7 +27,7 @@ namespace osu.Game.Skinning
var animation = new SkinnableTextureAnimation(startAtCurrentTime) var animation = new SkinnableTextureAnimation(startAtCurrentTime)
{ {
DefaultFrameLength = frameLength ?? getFrameLength(source, applyConfigFrameRate, textures), DefaultFrameLength = frameLength ?? getFrameLength(source, applyConfigFrameRate, textures),
Repeat = looping, Loop = looping,
}; };
foreach (var t in textures) foreach (var t in textures)
@ -71,7 +70,10 @@ namespace osu.Game.Skinning
base.LoadComplete(); base.LoadComplete();
if (timeReference != null) if (timeReference != null)
Clock = new FramedOffsetClock(timeReference.Clock) { Offset = -timeReference.AnimationStartTime }; {
Clock = timeReference.Clock;
PlaybackPosition = timeReference.AnimationStartTime - timeReference.Clock.CurrentTime;
}
} }
} }

View File

@ -108,7 +108,7 @@ namespace osu.Game.Storyboards.Drawables
Animation = animation; Animation = animation;
Origin = animation.Origin; Origin = animation.Origin;
Position = animation.InitialPosition; Position = animation.InitialPosition;
Repeat = animation.LoopType == AnimationLoopType.LoopForever; Loop = animation.LoopType == AnimationLoopType.LoopForever;
LifetimeStart = animation.StartTime; LifetimeStart = animation.StartTime;
LifetimeEnd = animation.EndTime; LifetimeEnd = animation.EndTime;

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Video; using osu.Framework.Graphics.Video;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
namespace osu.Game.Storyboards.Drawables namespace osu.Game.Storyboards.Drawables
@ -16,7 +15,7 @@ namespace osu.Game.Storyboards.Drawables
public class DrawableStoryboardVideo : CompositeDrawable public class DrawableStoryboardVideo : CompositeDrawable
{ {
public readonly StoryboardVideo Video; public readonly StoryboardVideo Video;
private VideoSprite videoSprite; private Video video;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
@ -40,14 +39,14 @@ namespace osu.Game.Storyboards.Drawables
if (stream == null) if (stream == null)
return; return;
InternalChild = videoSprite = new VideoSprite(stream, false) InternalChild = video = new Video(stream, false)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill, FillMode = FillMode.Fill,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Alpha = 0, Alpha = 0,
Clock = new FramedOffsetClock(Clock) { Offset = -Video.StartTime } PlaybackPosition = Video.StartTime
}; };
} }
@ -55,10 +54,10 @@ namespace osu.Game.Storyboards.Drawables
{ {
base.LoadComplete(); base.LoadComplete();
if (videoSprite == null) return; if (video == null) return;
using (videoSprite.BeginAbsoluteSequence(0)) using (video.BeginAbsoluteSequence(0))
videoSprite.FadeIn(500); video.FadeIn(500);
} }
} }
} }

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -47,16 +48,18 @@ namespace osu.Game.Tests.Visual
{ {
createdDrawables.Clear(); createdDrawables.Clear();
Cell(0).Child = createProvider(null, creationFunction); var beatmap = CreateBeatmapForSkinProvider();
Cell(1).Child = createProvider(metricsSkin, creationFunction);
Cell(2).Child = createProvider(defaultSkin, creationFunction); Cell(0).Child = createProvider(null, creationFunction, beatmap);
Cell(3).Child = createProvider(specialSkin, creationFunction); Cell(1).Child = createProvider(metricsSkin, creationFunction, beatmap);
Cell(4).Child = createProvider(oldSkin, creationFunction); Cell(2).Child = createProvider(defaultSkin, creationFunction, beatmap);
Cell(3).Child = createProvider(specialSkin, creationFunction, beatmap);
Cell(4).Child = createProvider(oldSkin, creationFunction, beatmap);
} }
protected IEnumerable<Drawable> CreatedDrawables => createdDrawables; protected IEnumerable<Drawable> CreatedDrawables => createdDrawables;
private Drawable createProvider(Skin skin, Func<Drawable> creationFunction) private Drawable createProvider(Skin skin, Func<Drawable> creationFunction, IBeatmap beatmap)
{ {
var created = creationFunction(); var created = creationFunction();
createdDrawables.Add(created); createdDrawables.Add(created);
@ -100,7 +103,7 @@ namespace osu.Game.Tests.Visual
{ {
new OutlineBox { Alpha = autoSize ? 1 : 0 }, new OutlineBox { Alpha = autoSize ? 1 : 0 },
mainProvider.WithChild( mainProvider.WithChild(
new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider)) new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider, beatmap))
{ {
Child = created, Child = created,
RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None, RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None,
@ -113,6 +116,8 @@ namespace osu.Game.Tests.Visual
}; };
} }
protected virtual IBeatmap CreateBeatmapForSkinProvider() => CreateWorkingBeatmap(Ruleset.Value).GetPlayableBeatmap(Ruleset.Value);
private class OutlineBox : CompositeDrawable private class OutlineBox : CompositeDrawable
{ {
public OutlineBox() public OutlineBox()

View File

@ -22,8 +22,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.402.1" /> <PackageReference Include="ppy.osu.Framework" Version="2020.403.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.402.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2020.403.0" />
<PackageReference Include="Sentry" Version="2.1.1" /> <PackageReference Include="Sentry" Version="2.1.1" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />

View File

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