mirror of
https://github.com/ppy/osu.git
synced 2026-05-15 12:42:48 +08:00
Compare commits
37 Commits
2020.402.0
...
2020.403.0
+2
-2
@@ -51,7 +51,7 @@
|
||||
<Reference Include="Java.Interop" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.331.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.401.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.402.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.402.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK.Graphics;
|
||||
@@ -37,10 +36,13 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
Child = new ScrollingHitObjectContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = new FramedClock(new StopwatchClock()),
|
||||
}.With(c =>
|
||||
{
|
||||
c.Add(CreateHitObject().With(h => h.AccentColour.Value = Color4.Orange));
|
||||
c.Add(CreateHitObject().With(h =>
|
||||
{
|
||||
h.HitObject.StartTime = START_TIME;
|
||||
h.AccentColour.Value = Color4.Orange;
|
||||
}));
|
||||
})
|
||||
},
|
||||
new ColumnTestContainer(1, ManiaAction.Key2)
|
||||
@@ -52,10 +54,13 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
Child = new ScrollingHitObjectContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = new FramedClock(new StopwatchClock()),
|
||||
}.With(c =>
|
||||
{
|
||||
c.Add(CreateHitObject().With(h => h.AccentColour.Value = Color4.Orange));
|
||||
c.Add(CreateHitObject().With(h =>
|
||||
{
|
||||
h.HitObject.StartTime = START_TIME;
|
||||
h.AccentColour.Value = Color4.Orange;
|
||||
}));
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
/// </summary>
|
||||
public abstract class ManiaSkinnableTestScene : SkinnableTestScene
|
||||
{
|
||||
protected const double START_TIME = 1000000000;
|
||||
|
||||
[Cached(Type = typeof(IScrollingInfo))]
|
||||
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||
|
||||
@@ -52,7 +54,26 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
|
||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
||||
IBindable<double> IScrollingInfo.TimeRange { get; } = new Bindable<double>(1000);
|
||||
IScrollAlgorithm IScrollingInfo.Algorithm { get; } = new ConstantScrollAlgorithm();
|
||||
IScrollAlgorithm IScrollingInfo.Algorithm { get; } = new ZeroScrollAlgorithm();
|
||||
}
|
||||
|
||||
private class ZeroScrollAlgorithm : IScrollAlgorithm
|
||||
{
|
||||
public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength)
|
||||
=> double.MinValue;
|
||||
|
||||
public float GetLength(double startTime, double endTime, double timeRange, float scrollLength)
|
||||
=> scrollLength;
|
||||
|
||||
public float PositionAt(double time, double currentTime, double timeRange, float scrollLength)
|
||||
=> (float)((time - START_TIME) / timeRange) * scrollLength;
|
||||
|
||||
public double TimeAt(float position, double currentTime, double timeRange, float scrollLength)
|
||||
=> 0;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+28
-24
@@ -3,42 +3,32 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneHitExplosion : OsuTestScene
|
||||
public class TestSceneHitExplosion : ManiaSkinnableTestScene
|
||||
{
|
||||
private ScrollingTestContainer scrolling;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(DrawableNote),
|
||||
typeof(DrawableManiaHitObject),
|
||||
};
|
||||
|
||||
protected override void LoadComplete()
|
||||
public TestSceneHitExplosion()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Child = scrolling = new ScrollingTestContainer(ScrollingDirection.Down)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativePositionAxes = Axes.Y,
|
||||
Y = -0.25f,
|
||||
Size = new Vector2(Column.COLUMN_WIDTH, DefaultNotePiece.NOTE_HEIGHT),
|
||||
};
|
||||
|
||||
int runcount = 0;
|
||||
|
||||
AddRepeatStep("explode", () =>
|
||||
@@ -48,15 +38,29 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
if (runcount % 15 > 12)
|
||||
return;
|
||||
|
||||
scrolling.AddRange(new Drawable[]
|
||||
CreatedDrawables.OfType<Container>().ForEach(c =>
|
||||
{
|
||||
new HitExplosion((runcount / 15) % 2 == 0 ? new Color4(94, 0, 57, 255) : new Color4(6, 84, 0, 255), runcount % 6 != 0)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
c.Add(new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion),
|
||||
_ => new DefaultHitExplosion((runcount / 15) % 2 == 0 ? new Color4(94, 0, 57, 255) : new Color4(6, 84, 0, 255), runcount % 6 != 0)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}));
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
SetContents(() => new ColumnTestContainer(0, ManiaAction.Key1)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativePositionAxes = Axes.Y,
|
||||
Y = -0.25f,
|
||||
Size = new Vector2(Column.COLUMN_WIDTH, DefaultNotePiece.NOTE_HEIGHT),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
@@ -10,15 +13,23 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||
{
|
||||
public class TestSceneHoldNote : ManiaHitObjectTestScene
|
||||
{
|
||||
public TestSceneHoldNote()
|
||||
{
|
||||
AddToggleStep("toggle hitting", v =>
|
||||
{
|
||||
foreach (var holdNote in CreatedDrawables.SelectMany(d => d.ChildrenOfType<DrawableHoldNote>()))
|
||||
{
|
||||
((Bindable<bool>)holdNote.IsHitting).Value = v;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override DrawableManiaHitObject CreateHitObject()
|
||||
{
|
||||
var note = new HoldNote { Duration = 1000 };
|
||||
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
|
||||
return new DrawableHoldNote(note)
|
||||
{
|
||||
Height = 200,
|
||||
};
|
||||
return new DrawableHoldNote(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,5 +26,6 @@ namespace osu.Game.Rulesets.Mania
|
||||
HoldNoteHead,
|
||||
HoldNoteTail,
|
||||
HoldNoteBody,
|
||||
HitExplosion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
if (!(sprite is TextureAnimation animation))
|
||||
return;
|
||||
|
||||
animation.GotoFrame(0);
|
||||
animation.IsPlaying = isHitting.NewValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
new LegacyManiaSkinConfigurationLookup(Stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightPosition))?.Value
|
||||
?? 0;
|
||||
|
||||
Color4 lineColour = GetManiaSkinConfig<Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLineColour)?.Value
|
||||
?? Color4.White;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@@ -57,6 +60,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = leftLineWidth,
|
||||
Colour = lineColour,
|
||||
Alpha = hasLeftLine ? 1 : 0
|
||||
},
|
||||
new Box
|
||||
@@ -65,6 +69,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = rightLineWidth,
|
||||
Colour = lineColour,
|
||||
Alpha = hasRightLine ? 1 : 0
|
||||
},
|
||||
lightContainer = new Container
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Animations;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Skinning
|
||||
{
|
||||
public class LegacyHitExplosion : LegacyManiaColumnElement
|
||||
{
|
||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||
|
||||
private Drawable explosion;
|
||||
|
||||
public LegacyHitExplosion()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
|
||||
{
|
||||
string imageName = GetManiaSkinConfig<string>(skin, LegacyManiaSkinConfigurationLookups.ExplosionImage)?.Value
|
||||
?? "lightingN";
|
||||
|
||||
float explosionScale = GetManiaSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.ExplosionScale)?.Value
|
||||
?? 1;
|
||||
|
||||
// Create a temporary animation to retrieve the number of frames, in an effort to calculate the intended frame length.
|
||||
// This animation is discarded and re-queried with the appropriate frame length afterwards.
|
||||
var tmp = skin.GetAnimation(imageName, true, false);
|
||||
double frameLength = 0;
|
||||
if (tmp is IAnimation tmpAnimation && tmpAnimation.FrameCount > 0)
|
||||
frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount);
|
||||
|
||||
explosion = skin.GetAnimation(imageName, true, false, startAtCurrentTime: true, frameLength: frameLength).With(d =>
|
||||
{
|
||||
if (d == null)
|
||||
return;
|
||||
|
||||
d.Origin = Anchor.Centre;
|
||||
d.Blending = BlendingParameters.Additive;
|
||||
d.Scale = new Vector2(explosionScale);
|
||||
});
|
||||
|
||||
if (explosion != null)
|
||||
InternalChild = explosion;
|
||||
|
||||
direction.BindTo(scrollingInfo.Direction);
|
||||
direction.BindValueChanged(onDirectionChanged, true);
|
||||
}
|
||||
|
||||
private void onDirectionChanged(ValueChangedEvent<ScrollingDirection> direction)
|
||||
{
|
||||
if (explosion != null)
|
||||
explosion.Anchor = direction.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
explosion?.FadeInFromZero(80)
|
||||
.Then().FadeOut(120);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
{
|
||||
protected override Texture GetTexture(ISkinSource skin)
|
||||
{
|
||||
// TODO: Should fallback to the head from default legacy skin instead of note.
|
||||
return GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage)
|
||||
?? GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage);
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
|
||||
protected override Texture GetTexture(ISkinSource skin)
|
||||
{
|
||||
// TODO: Should fallback to the head from default legacy skin instead of note.
|
||||
return GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteTailImage)
|
||||
?? GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage);
|
||||
?? GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage)
|
||||
?? GetTextureFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,9 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
|
||||
case ManiaSkinComponents.HoldNoteBody:
|
||||
return new LegacyBodyPiece();
|
||||
|
||||
case ManiaSkinComponents.HitExplosion:
|
||||
return new LegacyHitExplosion();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -105,11 +105,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value)
|
||||
return;
|
||||
|
||||
hitObjectArea.Explosions.Add(new HitExplosion(judgedObject.AccentColour.Value, judgedObject is DrawableHoldNoteTick)
|
||||
var explosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), _ =>
|
||||
new DefaultHitExplosion(judgedObject.AccentColour.Value, judgedObject is DrawableHoldNoteTick))
|
||||
{
|
||||
Anchor = Direction.Value == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre,
|
||||
Origin = Anchor.Centre
|
||||
});
|
||||
RelativeSizeAxes = Axes.Both
|
||||
};
|
||||
|
||||
hitObjectArea.Explosions.Add(explosion);
|
||||
|
||||
explosion.Delay(200).Expire(true);
|
||||
}
|
||||
|
||||
public bool OnPressed(ManiaAction action)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Skinning;
|
||||
@@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
||||
{
|
||||
public class ColumnHitObjectArea : HitObjectArea
|
||||
{
|
||||
public readonly Container<HitExplosion> Explosions;
|
||||
public readonly Container Explosions;
|
||||
private readonly Drawable hitTarget;
|
||||
|
||||
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
|
||||
@@ -25,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Depth = 1
|
||||
},
|
||||
Explosions = new Container<HitExplosion>
|
||||
Explosions = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Depth = -1,
|
||||
@@ -38,15 +37,9 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
||||
base.UpdateHitPosition();
|
||||
|
||||
if (Direction.Value == ScrollingDirection.Up)
|
||||
{
|
||||
hitTarget.Anchor = hitTarget.Origin = Anchor.TopLeft;
|
||||
Explosions.Padding = new MarginPadding { Top = DefaultNotePiece.NOTE_HEIGHT / 2 };
|
||||
}
|
||||
else
|
||||
{
|
||||
hitTarget.Anchor = hitTarget.Origin = Anchor.BottomLeft;
|
||||
Explosions.Padding = new MarginPadding { Bottom = DefaultNotePiece.NOTE_HEIGHT / 2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-3
@@ -1,26 +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.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
public class HitExplosion : CompositeDrawable
|
||||
public class DefaultHitExplosion : CompositeDrawable
|
||||
{
|
||||
public override bool RemoveWhenNotAlive => true;
|
||||
|
||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||
|
||||
private readonly CircularContainer largeFaint;
|
||||
private readonly CircularContainer mainGlow1;
|
||||
|
||||
public HitExplosion(Color4 objectColour, bool isSmall = false)
|
||||
public DefaultHitExplosion(Color4 objectColour, bool isSmall = false)
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = DefaultNotePiece.NOTE_HEIGHT;
|
||||
|
||||
@@ -109,6 +116,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IScrollingInfo scrollingInfo)
|
||||
{
|
||||
direction.BindTo(scrollingInfo.Direction);
|
||||
direction.BindValueChanged(onDirectionChanged, true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
const double duration = 200;
|
||||
@@ -122,7 +136,20 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
mainGlow1.ScaleTo(1.4f, duration, Easing.OutQuint);
|
||||
|
||||
this.FadeOut(duration, Easing.Out);
|
||||
Expire(true);
|
||||
}
|
||||
|
||||
private void onDirectionChanged(ValueChangedEvent<ScrollingDirection> direction)
|
||||
{
|
||||
if (direction.NewValue == ScrollingDirection.Up)
|
||||
{
|
||||
Anchor = Anchor.TopCentre;
|
||||
Y = DefaultNotePiece.NOTE_HEIGHT / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Anchor = Anchor.BottomCentre;
|
||||
Y = -DefaultNotePiece.NOTE_HEIGHT / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
@@ -13,8 +12,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Size = new Vector2(1, 0.8f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,30 +72,19 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
AutoSizeAxes = Axes.X,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
new Box
|
||||
{
|
||||
Name = "Columns mask",
|
||||
Name = "Background",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black
|
||||
},
|
||||
columnFlow = new FillFlowContainer<Column>
|
||||
{
|
||||
Name = "Columns",
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Name = "Background",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black
|
||||
},
|
||||
columnFlow = new FillFlowContainer<Column>
|
||||
{
|
||||
Name = "Columns",
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING },
|
||||
},
|
||||
}
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING },
|
||||
},
|
||||
new Container
|
||||
{
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
public LegacySliderBall(Drawable animationContent)
|
||||
{
|
||||
this.animationContent = animationContent;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
||||
@@ -62,17 +62,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
// Math.Max((150 / Velocity) * GameBase.SIXTY_FRAME_TIME, GameBase.SIXTY_FRAME_TIME);
|
||||
|
||||
if (sliderBallContent != null)
|
||||
{
|
||||
var size = sliderBallContent.Size;
|
||||
|
||||
sliderBallContent.RelativeSizeAxes = Axes.Both;
|
||||
sliderBallContent.Size = Vector2.One;
|
||||
|
||||
return new LegacySliderBall(sliderBallContent)
|
||||
{
|
||||
Size = size
|
||||
};
|
||||
}
|
||||
return new LegacySliderBall(sliderBallContent);
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[Mania]
|
||||
Keys: 4
|
||||
ColourBarline: 50,50,50,50
|
||||
@@ -5,6 +5,7 @@ using NUnit.Framework;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Skins
|
||||
{
|
||||
@@ -83,5 +84,20 @@ namespace osu.Game.Tests.Skins
|
||||
Assert.That(configs[0].HitPosition, Is.EqualTo(16));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestParseColours()
|
||||
{
|
||||
var decoder = new LegacyManiaSkinDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("mania-skin-colours.ini"))
|
||||
using (var stream = new LineBufferedReader(resStream))
|
||||
{
|
||||
var configs = decoder.Decode(stream);
|
||||
|
||||
Assert.That(configs.Count, Is.EqualTo(1));
|
||||
Assert.That(configs[0].CustomColours, Contains.Key("ColourBarline").And.ContainValue(new Color4(50, 50, 50, 50)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
switch (section)
|
||||
{
|
||||
case Section.Colours:
|
||||
handleColours(output, line);
|
||||
HandleColours(output, line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
return line;
|
||||
}
|
||||
|
||||
private void handleColours(T output, string line)
|
||||
protected void HandleColours<TModel>(TModel output, string line)
|
||||
{
|
||||
var pair = SplitKeyVal(line);
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ namespace osu.Game.Skinning
|
||||
/// <summary>
|
||||
/// Denotes an object which provides a reference time to start animations from.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This should not be used to start an animation immediately at the current time.
|
||||
/// To do so, use <see cref="LegacySkinExtensions.GetAnimation"/> with <code>startAtCurrentTime = true</code> instead.
|
||||
/// </remarks>
|
||||
[Cached]
|
||||
public interface IAnimationTimeReference
|
||||
{
|
||||
|
||||
@@ -2,19 +2,35 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyManiaSkinConfiguration
|
||||
public class LegacyManiaSkinConfiguration : IHasCustomColours
|
||||
{
|
||||
/// <summary>
|
||||
/// Conversion factor from converting legacy positioning values (based in x480 dimensions) to x768.
|
||||
/// </summary>
|
||||
public const float POSITION_SCALE_FACTOR = 1.6f;
|
||||
|
||||
/// <summary>
|
||||
/// Size of a legacy column in the default skin, used for determining relative scale factors.
|
||||
/// </summary>
|
||||
public const float DEFAULT_COLUMN_SIZE = 30 * POSITION_SCALE_FACTOR;
|
||||
|
||||
public readonly int Keys;
|
||||
|
||||
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
||||
|
||||
public readonly float[] ColumnLineWidth;
|
||||
public readonly float[] ColumnSpacing;
|
||||
public readonly float[] ColumnWidth;
|
||||
public readonly float[] ExplosionWidth;
|
||||
|
||||
public float HitPosition = 124.8f; // (480 - 402) * 1.6f
|
||||
public float LightPosition = 107.2f; // (480 - 413) * 1.6f
|
||||
public float HitPosition = (480 - 402) * POSITION_SCALE_FACTOR;
|
||||
public float LightPosition = (480 - 413) * POSITION_SCALE_FACTOR;
|
||||
public bool ShowJudgementLine = true;
|
||||
|
||||
public LegacyManiaSkinConfiguration(int keys)
|
||||
@@ -24,9 +40,10 @@ namespace osu.Game.Skinning
|
||||
ColumnLineWidth = new float[keys + 1];
|
||||
ColumnSpacing = new float[keys - 1];
|
||||
ColumnWidth = new float[keys];
|
||||
ExplosionWidth = new float[keys];
|
||||
|
||||
ColumnLineWidth.AsSpan().Fill(2);
|
||||
ColumnWidth.AsSpan().Fill(48);
|
||||
ColumnWidth.AsSpan().Fill(DEFAULT_COLUMN_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,5 +34,8 @@ namespace osu.Game.Skinning
|
||||
HoldNoteHeadImage,
|
||||
HoldNoteTailImage,
|
||||
HoldNoteBodyImage,
|
||||
ExplosionImage,
|
||||
ExplosionScale,
|
||||
ColumnLineColour
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyManiaSkinDecoder : LegacyDecoder<List<LegacyManiaSkinConfiguration>>
|
||||
{
|
||||
private const float size_scale_factor = 1.6f;
|
||||
|
||||
public LegacyManiaSkinDecoder()
|
||||
: base(1)
|
||||
{
|
||||
@@ -73,6 +71,12 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
var pair = SplitKeyVal(line);
|
||||
|
||||
if (pair.Key.StartsWith("Colour"))
|
||||
{
|
||||
HandleColours(currentConfig, line);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (pair.Key)
|
||||
{
|
||||
case "ColumnLineWidth":
|
||||
@@ -88,16 +92,20 @@ namespace osu.Game.Skinning
|
||||
break;
|
||||
|
||||
case "HitPosition":
|
||||
currentConfig.HitPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * size_scale_factor;
|
||||
currentConfig.HitPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
break;
|
||||
|
||||
case "LightPosition":
|
||||
currentConfig.LightPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * size_scale_factor;
|
||||
currentConfig.LightPosition = (480 - float.Parse(pair.Value, CultureInfo.InvariantCulture)) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
break;
|
||||
|
||||
case "JudgementLine":
|
||||
currentConfig.ShowJudgementLine = pair.Value == "1";
|
||||
break;
|
||||
|
||||
case "LightingNWidth":
|
||||
parseArrayValue(pair.Value, currentConfig.ExplosionWidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,7 +119,7 @@ namespace osu.Game.Skinning
|
||||
if (i >= output.Length)
|
||||
break;
|
||||
|
||||
output[i] = float.Parse(values[i], CultureInfo.InvariantCulture) * size_scale_factor;
|
||||
output[i] = float.Parse(values[i], CultureInfo.InvariantCulture) * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osuTK.Graphics;
|
||||
@@ -112,7 +113,7 @@ namespace osu.Game.Skinning
|
||||
break;
|
||||
|
||||
default:
|
||||
return SkinUtils.As<TValue>(getCustomColour(colour.ToString()));
|
||||
return SkinUtils.As<TValue>(getCustomColour(Configuration, colour.ToString()));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -130,7 +131,7 @@ namespace osu.Game.Skinning
|
||||
break;
|
||||
|
||||
case SkinCustomColourLookup customColour:
|
||||
return SkinUtils.As<TValue>(getCustomColour(customColour.Lookup.ToString()));
|
||||
return SkinUtils.As<TValue>(getCustomColour(Configuration, customColour.Lookup.ToString()));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookup maniaLookup:
|
||||
if (!AllowManiaSkin)
|
||||
@@ -192,12 +193,27 @@ namespace osu.Game.Skinning
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ShowJudgementLine:
|
||||
return SkinUtils.As<TValue>(new Bindable<bool>(existing.ShowJudgementLine));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ExplosionScale:
|
||||
Debug.Assert(maniaLookup.TargetColumn != null);
|
||||
|
||||
if (GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value < 2.5m)
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(1));
|
||||
|
||||
if (existing.ExplosionWidth[maniaLookup.TargetColumn.Value] != 0)
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.ExplosionWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE));
|
||||
|
||||
return SkinUtils.As<TValue>(new Bindable<float>(existing.ColumnWidth[maniaLookup.TargetColumn.Value] / LegacyManiaSkinConfiguration.DEFAULT_COLUMN_SIZE));
|
||||
|
||||
case LegacyManiaSkinConfigurationLookups.ColumnLineColour:
|
||||
return SkinUtils.As<TValue>(getCustomColour(existing, "ColourColumnLine"));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IBindable<Color4> getCustomColour(string lookup) => Configuration.CustomColours.TryGetValue(lookup, out var col) ? new Bindable<Color4>(col) : null;
|
||||
private IBindable<Color4> getCustomColour(IHasCustomColours source, string lookup)
|
||||
=> source.CustomColours.TryGetValue(lookup, out var col) ? new Bindable<Color4>(col) : null;
|
||||
|
||||
public override Drawable GetDrawableComponent(ISkinComponent component)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
public static class LegacySkinExtensions
|
||||
{
|
||||
public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-")
|
||||
public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-",
|
||||
bool startAtCurrentTime = false, double? frameLength = null)
|
||||
{
|
||||
Texture texture;
|
||||
|
||||
@@ -24,9 +25,9 @@ namespace osu.Game.Skinning
|
||||
|
||||
if (textures.Length > 0)
|
||||
{
|
||||
var animation = new SkinnableTextureAnimation
|
||||
var animation = new SkinnableTextureAnimation(startAtCurrentTime)
|
||||
{
|
||||
DefaultFrameLength = getFrameLength(source, applyConfigFrameRate, textures),
|
||||
DefaultFrameLength = frameLength ?? getFrameLength(source, applyConfigFrameRate, textures),
|
||||
Repeat = looping,
|
||||
};
|
||||
|
||||
@@ -60,8 +61,8 @@ namespace osu.Game.Skinning
|
||||
[Resolved(canBeNull: true)]
|
||||
private IAnimationTimeReference timeReference { get; set; }
|
||||
|
||||
public SkinnableTextureAnimation()
|
||||
: base(false)
|
||||
public SkinnableTextureAnimation(bool startAtCurrentTime = true)
|
||||
: base(startAtCurrentTime)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+20
-7
@@ -173,8 +173,27 @@ namespace osu.Game.Users
|
||||
public int Available;
|
||||
}
|
||||
|
||||
private UserStatistics statistics;
|
||||
|
||||
[JsonProperty(@"statistics")]
|
||||
public UserStatistics Statistics;
|
||||
public UserStatistics Statistics
|
||||
{
|
||||
get => statistics ??= new UserStatistics();
|
||||
set
|
||||
{
|
||||
if (statistics != null)
|
||||
// we may already have rank history populated
|
||||
value.RankHistory = statistics.RankHistory;
|
||||
|
||||
statistics = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(@"rankHistory")]
|
||||
private RankHistoryData rankHistory
|
||||
{
|
||||
set => statistics.RankHistory = value;
|
||||
}
|
||||
|
||||
public class RankHistoryData
|
||||
{
|
||||
@@ -185,12 +204,6 @@ namespace osu.Game.Users
|
||||
public int[] Data;
|
||||
}
|
||||
|
||||
[JsonProperty(@"rankHistory")]
|
||||
private RankHistoryData rankHistory
|
||||
{
|
||||
set => Statistics.RankHistory = value;
|
||||
}
|
||||
|
||||
[JsonProperty("badges")]
|
||||
public Badge[] Badges;
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
<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.Game.Resources" Version="2020.331.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.401.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.402.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.402.0" />
|
||||
<PackageReference Include="Sentry" Version="2.1.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
||||
+3
-3
@@ -70,8 +70,8 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.331.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.401.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.402.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.402.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.401.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.402.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
||||
Reference in New Issue
Block a user